/// <summary>
 /// Called when error occurs
 /// </summary>
 /// <param name="e">The exception that occurred</param>
 /// <param name="associatedMsg">The associated message (if any)</param>
 private void OnCoAPError(Exception e, AbstractCoAPMessage associatedMsg)
 {
     FileLogger.Write(e.Message);
     __Done.Set();
 }
        /// <summary>
        /// Called when a response is received against a sent request
        /// </summary>
        /// <param name="coapResp">The CoAPResponse object</param>
        private void OnCoAPDiscoveryResponseReceived(CoAPResponse coapResp)
        {
            __TimedOut = false;
            string tokenRx = "";// (coapResp.Token != null && coapResp.Token.Value != null) ? AbstractByteUtils.ByteToStringUTF8(coapResp.Token.Value) : "";

            if (coapResp != null)
            {
                if (coapResp.Token != null)
                {
                    tokenRx = AbstractByteUtils.ByteToStringUTF8(coapResp.Token.Value);
                }
            }
            try
            {
                FileLogger.Write("Received response from server - token = " + tokenRx);
                FileLogger.Write(coapResp.ToString());
            }
            catch { }

            if (tokenRx == __Token)
            {
                if (BreakIfError(coapResp.Code.Value))
                {
                    this.ErrorResult = coapResp.Code.ToString();
                    return;
                }

                if (coapResp.Code.Value == CoAPMessageCode.CONTENT)
                {
                    // Looks like we have the expected response.
                    // Check the content format and figure out how to store the response.
                    ArrayList options = coapResp.Options.GetOptions((ushort)CoAPHeaderOption.CONTENT_FORMAT);
                    if (options.Count > 0)
                    {
                        CoAPContentFormatOption ccformat = new CoAPContentFormatOption();
                        bool proceed = false;
                        foreach (CoAPHeaderOption o in options)
                        {
                            ccformat = new CoAPContentFormatOption(AbstractByteUtils.ToUInt16(o.Value));
                            if (ccformat.IsValid())
                            {
                                proceed = true;
                                break;
                            }
                        }
                        // The header options match what we expected.
                        // Set the discovery result.
                        if (proceed)
                        {
                            if (ccformat.Value == CoAPContentFormatOption.APPLICATION_LINK_FORMAT)
                            {
                                string discovery = AbstractByteUtils.ByteToStringUTF8(coapResp.Payload.Value);
                                __DiscoveryResult = discovery;
                            }

                            __Response = coapResp;
                            __Done.Set();
                        }
                    }
                }
                else
                {
                    //Will come here if an error occurred..
                }
            }
        }
        /// <summary>
        /// Load resources associated with a specific device.
        /// This is the CoAP Gateway implementation of CoApDiscovery.
        /// </summary>
        /// <returns>a collection of CoApResource objects</returns>
        ///
        public override CoApResources LoadResources()
        {
            // If we can't establish a socket with a good login to the gateway api, then just return;
            bool gotSession = false;

            try
            {
                gotSession = CoApGatewaySessionManager.Instance.EstablishSession();
            }
            catch (Exception noSession)
            {
                FileLogger.Write("Error obtaining session");
                FileLogger.Write(noSession.Message);
                FileLogger.Write(noSession.StackTrace);
                this.ErrorResult = "Error obtaining session" + noSession.Message;
            }

            if (!gotSession)
            {
                FileLogger.Write("Session NOT Established");
                return(null);
            }

            // This represents the device being examined.
            string serverIP = __IpAddress;

            // Set up the notification handlers.
            CoApGatewaySessionManager.Instance.Client.CoAPResponseReceived += new CoAPResponseReceivedHandler(OnCoAPDiscoveryResponseReceived);
            CoApGatewaySessionManager.Instance.Client.CoAPError            += new CoAPErrorHandler(OnCoAPDiscoveryError);
            __TimedOut = true;

            // Discovery requires confirmation and a message type of GET
            coapReq = new CoAPRequest(this.ConfirmableMessageType,
                                      CoAPMessageCode.GET,
                                      HdkUtils.MessageId());

            string uriToCall = "coap://" + UriFromMac(__IpAddress) + ":" + __ServerPort + "/.well-known/core";//"/.well-known/core";

            coapReq.SetURL(uriToCall);
            SetToken();
            // Send out the coap request

            // JJK - Change in v2.0.7
            //coapReq.Options.AddOption(CoAPHeaderOption.PROXY_SCHEME, "coap");
            // make Proxy packet Change in v2.0.7
            coapReq.Options.AddOption(CoAPHeaderOption.BLOCK2, new byte[] { CoAPBlockOption.BLOCK_SIZE_128 });
            //coapReq.Options.AddOption(CoAPHeaderOption.PROXY_URI, "coap://SSN001350050047dc9a.SG.YEL01.SSN.SSNSGS.NET:4849/.well-known/core");
            coapReq.Options.AddOption(CoAPHeaderOption.PROXY_URI, "coap://" + UriFromMac(__IpAddress) + ":" + "4849" + "/.well-known/core");
            coapReq.Options.RemoveOption(CoAPHeaderOption.URI_HOST);
            coapReq.Options.RemoveOption(CoAPHeaderOption.URI_QUERY);
            coapReq.Options.RemoveOption(CoAPHeaderOption.URI_PATH);
            coapReq.Options.RemoveOption(CoAPHeaderOption.URI_PORT);
            coapReq.Options.RemoveOption(CoAPHeaderOption.CONTENT_FORMAT);
            // end of Changes in v2.0.7

            FileLogger.Write("About to send Gateway resource request");
            FileLogger.Write(coapReq.ToString());
            CoApGatewaySessionManager.Instance.Client.Send(coapReq);

            CoApDiscoveryResponse response = null;

            // Wait for a response from the discovery request.
            // Time out after the pre-defined maximum wait time.
            __Done.WaitOne(GatewaySettings.Instance.RequestTimeout);
            response = this.DiscoveryResponse;

            // Reset the wait object
            __Done.Reset();
            if (__TimedOut)
            {
                this.ErrorResult = "Request timed out";
            }
            // Remove event handlers.
            CoApGatewaySessionManager.Instance.Client.CoAPResponseReceived -= new CoAPResponseReceivedHandler(OnCoAPDiscoveryResponseReceived);
            CoApGatewaySessionManager.Instance.Client.CoAPError            -= new CoAPErrorHandler(OnCoAPDiscoveryError);
            return(response.Resources);
        }
        /// <summary>
        /// Find all Gateway registered CoAP devices.
        /// </summary>
        /// <returns>A list of CoApDevice objects representing all registered devices</returns>
        public override CoApDevices LoadNodes()
        {
            CoAPSettings.Instance.AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6;//.InterNetwork;
            CoApDevices devices = new CoApDevices();

            DevicesResponse jsonDevices;

            // Use SLDP API to fetch a list of devices.
            jsonDevices = GetDevices();
            if (jsonDevices != null)
            {
                foreach (SLDPAPI.DevicesResponse.Device dev in jsonDevices.devices)
                {
                    if (dev != null)
                    {
                        if (dev.deviceType == "MILLI")// && dev.domainInfo.nic_macID == "001350050047dc1f")// || dev.domainInfo.nic_macID == "001350050047dd88")
                        {
                            string mac = dev.domainInfo.nic_macID;
                            FileLogger.Write("Processing MAC " + mac);
                            CoApDevice d = new CoApDevice(mac);
                            devices.Add(d);
                            // If the ping fails then tag it as unreachable
                            //if (!j.Succeeded)
                            //{
                            //    d.Name = "UNREACHABLE - " + d.Name;
                            //    d.Reachable = false;
                            //}
                            //else
                            //{
                            d.Reachable = true;
                            //}
                        }
                    }
                }
                //if (jsonDevices.deviceSearch.queryResults != null)
                //{
                //    // Look through all discovered devices and add non-AP devices to the device list.
                //    for (int i = 0; i < jsonDevices.deviceSearch.queryResults.Count; i++)
                //    {

                //        FileLogger.Write("Processing MAC " + jsonDevices.deviceSearch.queryResults[i].nic_macId);
                //        if (jsonDevices.deviceSearch.queryResults[i].nic_imageType == "ACCESS_POINT")
                //        {
                //            FileLogger.Write("Ignoring access point " + jsonDevices.deviceSearch.queryResults[i].nic_macId);
                //        }

                //        // Ignore access points
                //        if (jsonDevices.deviceSearch.queryResults[i].nic_imageType != "ACCESS_POINT")
                //        {
                //            CoApDevice d = new CoApDevice(jsonDevices.deviceSearch.queryResults[i].nic_macId);
                //            devices.Add(d);
                //            // Ping the device
                //            //string ping = PingMacOLD(d.Name);
                //            //// Translate the ping JSON response into an equivalent C# object
                //            //PingResponseGateway j = new PingResponseGateway(ping);
                //            //// If the ping fails then tag it as unreachable
                //            //if (!j.Succeeded)
                //            //{
                //            //    d.Name = "UNREACHABLE - " + d.Name;
                //            //    d.Reachable = false;
                //            //}
                //            //else
                //            //{
                //            //    d.Reachable = true;
                //            //}
                //            bool ping = PingMac(d.Name);
                //            // If the ping fails then tag it as unreachable
                //            if (!ping)
                //            {
                //                d.Name = "UNREACHABLE - " + d.Name;
                //                d.Reachable = false;
                //            }
                //            else
                //            {
                //                d.Reachable = true;
                //            }
                //        }
                //    }
                //}
            }

            return(devices);
        }