Ejemplo n.º 1
0
        public override List <Field> ProcessReadoutRequest(ReadoutType Types, DateTime From, DateTime To)
        {
            String           Path   = this.resource;
            EditableTreeNode Node   = this.Parent;
            CoapServer       Server = null;
            CoapFolder       Folder;

            while (Node != null)
            {
                if ((Folder = Node as CoapFolder) != null)
                {
                    Path = Folder.Folder + "/" + Path;
                }
                else if ((Server = Node as CoapServer) != null)
                {
                    break;
                }

                Node = Node.Parent;
            }

            if (Server == null)
            {
                throw new Exception("No CoAP Server node found.");
            }

            CoapEndpoint Endpoint = Server.Endpoint;
            CoapResponse Response = Endpoint.GET(true, Server.Host, Server.Port, Path, this.query, 20000);

            return(this.ParseContent(Response.Response, Types, From, To));
        }
Ejemplo n.º 2
0
        private void ReturnMomentaryAsXml(CoapMessage Request, CoapResponse Response)
        {
            StringBuilder s = new StringBuilder();

            s.Append("<m ts='");
            s.Append(DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
            s.Append("'>");

            if (this.lastLight.HasValue)
            {
                s.Append("<l u='%'>");
                s.Append(ToString(this.lastLight.Value, 2));
                s.Append("</l>");
            }

            if (this.lastMotion.HasValue)
            {
                s.Append("<md>");
                s.Append(this.lastMotion.Value ? "true" : "false");
                s.Append("</md>");
            }

            s.Append("</m>");

            Response.Respond(CoapCode.Content, s.ToString(), 64, new CoapOptionContentFormat(Xml.ContentFormatCode));
        }
Ejemplo n.º 3
0
        private void ReturnMomentaryAsJson(CoapMessage Request, CoapResponse Response)
        {
            StringBuilder s = new StringBuilder();

            s.Append("{\"ts\":\"");
            s.Append(DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
            s.Append('"');

            if (this.lastLight.HasValue)
            {
                s.Append(",\"l\":{\"v\":");
                s.Append(ToString(this.lastLight.Value, 2));
                s.Append(",\"u\":\"%\"}");
            }

            if (this.lastMotion.HasValue)
            {
                s.Append(",\"md\":");
                s.Append(this.lastMotion.Value ? "true" : "false");
            }

            s.Append('}');

            Response.Respond(CoapCode.Content, s.ToString(), 64, new CoapOptionContentFormat(Json.ContentFormatCode));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Executes the PUT method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public void PUT(CoapMessage Request, CoapResponse Response)
        {
            if (this.Client.State == Lwm2mState.Bootstrap &&
                this.Client.IsFromBootstrapServer(Request))
            {
                if (!string.IsNullOrEmpty(Request.SubPath) &&
                    ushort.TryParse(Request.SubPath.Substring(1), out ushort InstanceId))
                {
                    Lwm2mSecurityObjectInstance Instance = new Lwm2mSecurityObjectInstance(InstanceId);
                    this.Add(Instance);
                    this.Client.Endpoint.Register(Instance);
                    Instance.AfterRegister(this.Client);

                    Request.Path   += Request.SubPath;
                    Request.SubPath = string.Empty;

                    Instance.PUT(Request, Response);
                }
                else
                {
                    Response.RST(CoapCode.BadRequest);
                }
            }
            else
            {
                Response.RST(CoapCode.Unauthorized);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Executes the GET method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public void GET(CoapMessage Request, CoapResponse Response)
        {
            bool FromBootstrapServer = this.client.IsFromBootstrapServer(Request);

            if (this.id == 0 && !FromBootstrapServer)
            {
                Response.RST(CoapCode.Unauthorized);
                return;
            }

            if (!string.IsNullOrEmpty(Request.SubPath))
            {
                Response.RST(CoapCode.NotFound);
                return;
            }

            if (!Request.IsAcceptable(CoreLinkFormat.ContentFormatCode))
            {
                Response.RST(CoapCode.NotAcceptable);
                return;
            }

            StringBuilder Output = new StringBuilder();

            this.EncodeObjectLinks(this.client.State == Lwm2mState.Bootstrap && FromBootstrapServer, Output);

            Response.Respond(CoapCode.Content, Encoding.UTF8.GetBytes(Output.ToString()), 64,
                             new CoapOptionContentFormat(CoreLinkFormat.ContentFormatCode));
        }
        /// <summary>
        /// Not implemented in client
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public Task <CoapMessage> ObserveAsync(CoapMessage message)
        {
            TaskCompletionSource <CoapMessage> tcs = new TaskCompletionSource <CoapMessage>();
            CoapMessage msg = new CoapResponse(message.MessageId, ResponseMessageType.Reset, ResponseCodeType.EmptyMessage, message.Token);

            tcs.SetResult(msg);
            return(tcs.Task);
        }
Ejemplo n.º 7
0
        public static byte[] ConvertToCoap(CoapSession session, EventMessage message, byte[] observableToken = null)
        {
            CoapMessage coapMessage = null;
            CoapToken   token       = CoapToken.Create();

            ushort id = observableToken == null?session.CoapSender.NewId(token.TokenBytes) : session.CoapSender.NewId(observableToken);

            string uriString = CoapUri.Create(session.Config.Authority, message.ResourceUri, IsEncryptedChannel);

            if (message.Protocol == ProtocolType.MQTT)
            {
                MqttMessage    msg = MqttMessage.DecodeMessage(message.Message);
                PublishMessage pub = msg as PublishMessage;
                MqttUri        uri = new MqttUri(pub.Topic);
                if (observableToken == null)
                {
                    RequestMessageType messageType = msg.QualityOfService == QualityOfServiceLevelType.AtMostOnce ? RequestMessageType.NonConfirmable : RequestMessageType.Confirmable;
                    //request
                    coapMessage = new CoapRequest(id, messageType, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType));
                }
                else
                {
                    //response
                    coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(uri.ContentType), msg.Payload);
                }
            }
            else if (message.Protocol == ProtocolType.COAP)
            {
                CoapMessage msg = CoapMessage.DecodeMessage(message.Message);
                if (observableToken == null)
                {
                    //request
                    coapMessage = new CoapRequest(id, msg.MessageType == CoapMessageType.Confirmable ? RequestMessageType.Confirmable : RequestMessageType.NonConfirmable, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType), msg.Payload);
                }
                else
                {
                    //response
                    coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(message.ContentType), msg.Payload);
                }
            }
            else
            {
                if (observableToken == null)
                {
                    //request
                    coapMessage = new CoapRequest(id, RequestMessageType.NonConfirmable, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType), message.Message);
                }
                else
                {
                    //response
                    coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(message.ContentType), message.Message);
                }
            }

            return(coapMessage.Encode());
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Executes the GET method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public virtual void GET(CoapMessage Request, CoapResponse Response)
        {
            ILwm2mWriter Writer;
            bool         FromBootstrapServer = this.objInstance.Object.Client.IsFromBootstrapServer(Request);

            if (this.id == 0 && !FromBootstrapServer)
            {
                Response.RST(CoapCode.Unauthorized);
                return;
            }

            if (Request.Accept is null)
            {
                Writer = new TextWriter();
            }
            else if (Request.IsAcceptable(Tlv.ContentFormatCode))
            {
                Writer = new TlvWriter();
            }
            else if (Request.IsAcceptable(Json.ContentFormatCode))
            {
                Writer = new JsonWriter(this.objInstance.Path + "/");
            }
            else if (Request.IsAcceptable(CoAP.ContentFormats.PlainText.ContentFormatCode))
            {
                Writer = new TextWriter();
            }
            else if (Request.IsAcceptable(CoAP.ContentFormats.Binary.ContentFormatCode))
            {
                Writer = new OpaqueWriter();
            }
            else
            {
                Response.RST(CoapCode.NotAcceptable);
                return;
            }

            if (this.OnBeforeGet != null)
            {
                try
                {
                    this.OnBeforeGet.Invoke(this, new CoapRequestEventArgs(Request));
                }
                catch (Exception ex)
                {
                    Log.Critical(ex);
                }
            }

            this.Write(Writer);

            byte[] Payload = Writer.ToArray();

            Response.Respond(CoapCode.Content, Payload, 64,
                             new CoapOptionContentFormat(Writer.ContentFormat));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Executes the GET method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public virtual void GET(CoapMessage Request, CoapResponse Response)
        {
            ILwm2mWriter Writer;
            bool         FromBootstrapServer = this.obj.Client.IsFromBootstrapServer(Request);

            if (this.id == 0 && !FromBootstrapServer)
            {
                Response.RST(CoapCode.Unauthorized);
                return;
            }

            if (!string.IsNullOrEmpty(Request.SubPath))
            {
                Response.RST(CoapCode.NotFound);
                return;
            }

            if (Request.IsAcceptable(Tlv.ContentFormatCode))
            {
                Writer = new TlvWriter();
            }
            else if (Request.IsAcceptable(Json.ContentFormatCode))
            {
                Writer = new JsonWriter(this.Path + "/");
            }
            else if (Request.IsAcceptable(CoAP.ContentFormats.CoreLinkFormat.ContentFormatCode))
            {
                StringBuilder Output = new StringBuilder();
                this.EncodeObjectLinks(FromBootstrapServer, Output);

                Response.Respond(CoapCode.Content, Encoding.UTF8.GetBytes(Output.ToString()), 64,
                                 new CoapOptionContentFormat(CoAP.ContentFormats.CoreLinkFormat.ContentFormatCode));

                return;
            }
            else
            {
                Response.RST(CoapCode.NotAcceptable);
                return;
            }

            this.Export(Writer);

            byte[] Payload = Writer.ToArray();

            if (Payload.Length == 0)
            {
                Response.RST(CoapCode.NotFound);
            }
            else
            {
                Response.Respond(CoapCode.Content, Payload, 64,
                                 new CoapOptionContentFormat(Writer.ContentFormat));
            }
        }
 /// <summary>
 /// Executes the GET method on the resource.
 /// </summary>
 /// <param name="Request">CoAP Request</param>
 /// <param name="Response">CoAP Response</param>
 /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
 public override void GET(CoapMessage Request, CoapResponse Response)
 {
     if (this.Object.Client.IsFromBootstrapServer(Request))
     {
         base.GET(Request, Response);
     }
     else
     {
         Response.RST(CoapCode.Unauthorized);
     }
 }
Ejemplo n.º 11
0
 public static void PrintResponse(CoapResponse response)
 {
     Console.WriteLine("> RESPONSE");
     Console.WriteLine("   + Status         = " + response.StatusCode);
     Console.WriteLine("   + Status code    = " + (int)response.StatusCode);
     Console.WriteLine("   + Content format = " + response.Options.ContentFormat);
     Console.WriteLine("   + Max age        = " + response.Options.MaxAge);
     Console.WriteLine("   + E tag          = " + ByteArrayToString(response.Options.ETag));
     Console.WriteLine("   + Payload        = " + Encoding.UTF8.GetString(response.Payload));
     Console.WriteLine();
 }
Ejemplo n.º 12
0
 public void POST(CoapMessage Request, CoapResponse Response)
 {
     if (this.client.IsFromBootstrapServer(Request))
     {
         Task T = this.client.BootstrapCompleted();
         Response.Respond(CoapCode.Changed);
     }
     else
     {
         Response.RST(CoapCode.Unauthorized);
     }
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Executes the DELETE method on the resource.
 /// </summary>
 /// <param name="Request">CoAP Request</param>
 /// <param name="Response">CoAP Response</param>
 /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
 public void DELETE(CoapMessage Request, CoapResponse Response)
 {
     if (this.Object.Client.State == Lwm2mState.Bootstrap &&
         this.Object.Client.IsFromBootstrapServer(Request))
     {
         Task T = this.DeleteBootstrapInfo();
         Response.ACK(CoapCode.Deleted);
     }
     else
     {
         Response.RST(CoapCode.Unauthorized);
     }
 }
        public Task <CoapMessage> PostAsync(CoapMessage message)
        {
            TaskCompletionSource <CoapMessage> tcs = new TaskCompletionSource <CoapMessage>();
            CoapUri             uri = new CoapUri(message.ResourceUri.ToString());
            ResponseMessageType rmt = message.MessageType == CoapMessageType.Confirmable ? ResponseMessageType.Acknowledgement : ResponseMessageType.NonConfirmable;


            registry.GetAction("POST", uri.Resource)?.Invoke(MediaTypeConverter.ConvertFromMediaType(message.ContentType), message.Payload);
            CoapMessage response = new CoapResponse(message.MessageId, rmt, ResponseCodeType.Created, message.Token);

            tcs.SetResult(response);
            return(tcs.Task);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Executes the DELETE method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public void DELETE(CoapMessage Request, CoapResponse Response)
        {
            if (this.state != Lwm2mState.Bootstrap)
            {
                if (this.IsFromBootstrapServer(Request))
                {
                    this.State = Lwm2mState.Bootstrap;
                }
                else
                {
                    Response.RST(CoapCode.Unauthorized);
                    return;
                }
            }

            Task T = this.DeleteBootstrapInfo();

            Response.ACK(CoapCode.Deleted);
        }
Ejemplo n.º 16
0
        private void ReturnMomentaryAsPlainText(CoapMessage Request, CoapResponse Response)
        {
            StringBuilder s = new StringBuilder();

            s.Append("Timestamp: ");
            s.AppendLine(DateTime.Now.ToUniversalTime().ToString());

            if (this.lastLight.HasValue)
            {
                s.Append("Light: ");
                s.Append(ToString(this.lastLight.Value, 2));
                s.AppendLine(" %");
            }

            if (this.lastMotion.HasValue)
            {
                s.Append("Motion detected: ");
                s.AppendLine(this.lastMotion.Value ? "true" : "false");
            }

            Response.Respond(CoapCode.Content, s.ToString(), 64);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Executes the PUT method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public virtual void PUT(CoapMessage Request, CoapResponse Response)
        {
            bool FromBootstrapServer = this.obj.Client.IsFromBootstrapServer(Request);

            if (this.id == 0 && !FromBootstrapServer)
            {
                Response.RST(CoapCode.Unauthorized);
                return;
            }

            if (Request.UriQuery != null && Request.UriQuery.Count > 0)                // Write attributes
            {
                if (!FromBootstrapServer)
                {
                    Response.RST(CoapCode.Unauthorized);
                    return;
                }

                foreach (KeyValuePair <string, string> P in Request.UriQuery)
                {
                    switch (P.Key)
                    {
                    case "pmin":
                    case "pmax":
                    case "gt":
                    case "lt":
                    case "st":
                        // TODO: Implement support
                        break;

                    default:
                        Response.RST(CoapCode.BadRequest);
                        return;
                    }
                }
            }

            if (Request.ContentFormat != null)                  // Write operation
            {
                object Decoded = Request.Decode();

                if (Decoded is TlvRecord[] Records)
                {
                    LinkedList <KeyValuePair <Lwm2mResource, TlvRecord> > ToWrite =
                        new LinkedList <KeyValuePair <Lwm2mResource, TlvRecord> >();

                    lock (this.resources)
                    {
                        foreach (TlvRecord Rec in Records)
                        {
                            if (!this.resources.TryGetValue(Rec.Identifier, out Lwm2mResource Resource) ||
                                (!Resource.CanWrite && !FromBootstrapServer))
                            {
                                ToWrite = null;
                                break;
                            }

                            ToWrite.AddLast(new KeyValuePair <Lwm2mResource, TlvRecord>(Resource, Rec));
                        }
                    }

                    if (ToWrite is null)
                    {
                        Response.Respond(CoapCode.BadRequest);
                        return;
                    }

                    if (Request.Code == CoapCode.PUT)                       // POST updates, PUT recreates
                    {
                        foreach (Lwm2mResource Resource in this.Resources)
                        {
                            Resource.Reset();
                        }
                    }

                    foreach (KeyValuePair <Lwm2mResource, TlvRecord> Rec in ToWrite)
                    {
                        Rec.Key.Read(Rec.Value);
                        Rec.Key.RemoteUpdate(Request);
                    }
                }
                else
                {
                    Response.Respond(CoapCode.NotAcceptable);
                    return;
                }
            }
            else
            {
                Response.Respond(CoapCode.BadRequest);
                return;
            }

            Response.Respond(CoapCode.Changed);
        }
Ejemplo n.º 18
0
 public void PUT(CoapMessage Request, CoapResponse Response)
 {
     Response.Respond(CoapCode.Changed, Request.Payload, 64);
 }
Ejemplo n.º 19
0
        /// <summary>
        /// Executes the PUT method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public virtual void PUT(CoapMessage Request, CoapResponse Response)
        {
            bool FromBootstrapServer = this.objInstance.Object.Client.IsFromBootstrapServer(Request);

            if (this.id == 0 && !FromBootstrapServer)
            {
                Response.RST(CoapCode.Unauthorized);
                return;
            }

            if (Request.UriQuery != null && Request.UriQuery.Count > 0)                // Write attributes
            {
                if (!FromBootstrapServer)
                {
                    Response.RST(CoapCode.Unauthorized);
                    return;
                }

                foreach (KeyValuePair <string, string> P in Request.UriQuery)
                {
                    switch (P.Key)
                    {
                    case "pmin":
                    case "pmax":
                    case "gt":
                    case "lt":
                    case "st":
                        // TODO: Implement support
                        break;

                    default:
                        Response.RST(CoapCode.BadRequest);
                        return;
                    }
                }
            }

            if (Request.ContentFormat != null)                  // Write operation
            {
                if (!this.canWrite && !FromBootstrapServer)
                {
                    Response.Respond(CoapCode.BadRequest);
                    return;
                }

                object Decoded = Request.Decode();

                if (Decoded is TlvRecord[] Records)
                {
                    foreach (TlvRecord Rec in Records)
                    {
                        this.Read(Rec);
                    }
                }
                else
                {
                    Response.Respond(CoapCode.NotAcceptable);
                    return;
                }

                this.RemoteUpdate(Request);
            }
            else
            {
                this.Execute(Request);
            }

            Response.Respond(CoapCode.Changed);
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Executes the POST method on the resource.
 /// </summary>
 /// <param name="Request">CoAP Request</param>
 /// <param name="Response">CoAP Response</param>
 /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
 public void POST(CoapMessage Request, CoapResponse Response)
 {
     this.PUT(Request, Response);
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Executes the GET method on the resource.
 /// </summary>
 /// <param name="Request">CoAP Request</param>
 /// <param name="Response">CoAP Response</param>
 /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
 public override void GET(CoapMessage Request, CoapResponse Response)
 {
     Response.Respond(CoapCode.MethodNotAllowed);
 }
Ejemplo n.º 22
0
        /// <summary>
        /// Executes the GET method on the resource.
        /// </summary>
        /// <param name="Request">CoAP Request</param>
        /// <param name="Response">CoAP Response</param>
        /// <exception cref="CoapException">If an error occurred when processing the method.</exception>
        public void GET(CoapMessage Request, CoapResponse Response)
        {
            StringBuilder sb = new StringBuilder();

            CoapResource[] Resources = this.endpoint.GetResources();
            LinkedList <KeyValuePair <string, string> > Filter = null;
            bool   First = true;
            string s;
            int    i, c;
            bool   Include;

            foreach (CoapOption Option in Request.Options)
            {
                if (Option is CoapOptionUriQuery Query)
                {
                    if (Filter is null)
                    {
                        Filter = new LinkedList <KeyValuePair <string, string> >();
                    }

                    Filter.AddLast(new KeyValuePair <string, string>(Query.Key, Query.KeyValue));
                }
            }

            foreach (CoapResource Resource in Resources)
            {
                if (!Resource.WellKnownCoRE)
                {
                    continue;
                }

                if (Filter != null)
                {
                    Include = true;

                    foreach (KeyValuePair <string, string> Rec in Filter)
                    {
                        switch (Rec.Key)
                        {
                        case "href":
                            Include = this.Matches(Rec.Value, Resource.Path);
                            break;

                        case "rt":
                            Include = this.Matches(Rec.Value, Resource.ResourceTypes);
                            break;

                        case "if":
                            Include = this.Matches(Rec.Value, Resource.InterfaceDescriptions);
                            break;

                        case "ct":
                            Include = this.Matches(Rec.Value, Resource.ContentFormats);
                            break;

                        case "obs":
                            Include = Resource.Observable;
                            break;

                        case "title":
                            Include = this.Matches(Rec.Value, Resource.Title);
                            break;

                        case "sz":
                            if (!Resource.MaximumSizeEstimate.HasValue)
                            {
                                Include = false;
                            }
                            else
                            {
                                Include = this.Matches(Rec.Value, Resource.MaximumSizeEstimate.Value.ToString());
                            }
                            break;

                        default:
                            Include = false;
                            break;
                        }
                    }

                    if (!Include)
                    {
                        continue;
                    }
                }

                if (First)
                {
                    First = false;
                }
                else
                {
                    sb.Append(',');
                }

                sb.Append('<');
                sb.Append(Resource.Path);
                sb.Append('>');

                if (Resource.Observable)
                {
                    sb.Append(";obs");
                }

                if (!string.IsNullOrEmpty(s = Resource.Title))
                {
                    sb.Append(";title=\"");
                    sb.Append(s.Replace("\"", "\\\""));
                    sb.Append("\"");
                }

                this.Append(sb, "rt", Resource.ResourceTypes);
                this.Append(sb, "if", Resource.InterfaceDescriptions);

                int[] ContentFormats = Resource.ContentFormats;
                if (ContentFormats != null && (c = ContentFormats.Length) > 0)
                {
                    sb.Append(";ct=\"");

                    for (i = 0; i < c; i++)
                    {
                        if (i > 0)
                        {
                            sb.Append(' ');
                        }

                        sb.Append(ContentFormats[i].ToString());
                    }

                    sb.Append('"');
                }

                if (Resource.MaximumSizeEstimate.HasValue)
                {
                    sb.Append(";sz=");
                    sb.Append(Resource.MaximumSizeEstimate.Value.ToString());
                }
            }

            Response.Respond(CoapCode.Content, Encoding.UTF8.GetBytes(sb.ToString()),
                             64, new CoapOptionContentFormat(CoreLinkFormat.ContentFormatCode));
        }