internal async Task <DacpResponse> SendRequestAsync(string uri, CancellationToken cancellationToken)
        {
            _log.Info("Sending request for: " + uri);

            Task <HttpResponseMessage> task;

            lock (_httpClient)
                task = _httpClient.GetAsync(new Uri(HttpPrefix + uri)).AsTask(cancellationToken);
            HttpResponseMessage response = await task.ConfigureAwait(false);

            if (!response.IsSuccessStatusCode)
            {
                throw new DacpRequestException(response);
            }

            var buffer = await response.Content.ReadAsBufferAsync().AsTask(cancellationToken).ConfigureAwait(false);

            var reader = DataReader.FromBuffer(buffer);

            byte[] data = new byte[reader.UnconsumedBufferLength];
            reader.ReadBytes(data);

            _log.Info("Received response for: {0} (source: {1})", uri, response.Source);

            // Get the content of the first node
            IEnumerable <DacpNode> nodes = null;

            if (data.Length > 0)
            {
                data  = DacpUtility.GetResponseNodes(data, true).First().Value;
                nodes = DacpUtility.GetResponseNodes(data);
            }

            return(new DacpResponse(response, nodes));
        }
예제 #2
0
 public long GetLong(string key, long defaultValue = default(long))
 {
     if (!this.ContainsKey(key))
     {
         return(defaultValue);
     }
     return(DacpUtility.GetInt64Value(this[key]));
 }
예제 #3
0
 public bool GetBool(string key, bool defaultValue = default(bool))
 {
     if (!this.ContainsKey(key))
     {
         return(defaultValue);
     }
     return(DacpUtility.GetBoolValue(this[key]));
 }
예제 #4
0
 public short?GetNullableShort(string key, short?defaultValue = default(short?))
 {
     if (!this.ContainsKey(key))
     {
         return(defaultValue);
     }
     return(DacpUtility.GetInt16Value(this[key]));
 }
예제 #5
0
 public int?GetNullableInt(string key, int?defaultValue = default(int?))
 {
     if (!this.ContainsKey(key))
     {
         return(defaultValue);
     }
     return(DacpUtility.GetInt32Value(this[key]));
 }
예제 #6
0
 public string GetString(string key, string defaultValue = default(string))
 {
     if (!this.ContainsKey(key))
     {
         return(defaultValue);
     }
     return(DacpUtility.GetStringValue(this[key]));
 }
예제 #7
0
 public DateTime GetDateTime(string key, DateTime defaultValue = default(DateTime))
 {
     if (!this.ContainsKey(key))
     {
         return(defaultValue);
     }
     return(DacpUtility.GetDateTimeValue(this[key]));
 }
        internal async Task <IDacpList> GetAlphaGroupedListAsync <T>(DacpRequest request, Func <byte[], T> itemGenerator, string listKey = DacpUtility.DefaultListKey)
        {
            try
            {
                var response = await SendRequestAsync(request).ConfigureAwait(false);

                return(DacpUtility.GetAlphaGroupedDacpList(response.Nodes, itemGenerator, listKey));
            }
            catch (Exception)
            {
                return(new DacpList <T>(false));
            }
        }
        internal async Task <List <T> > GetListAsync <T>(DacpRequest request, Func <DacpNodeDictionary, T> itemGenerator, string listKey = DacpUtility.DefaultListKey)
        {
            try
            {
                var response = await SendRequestAsync(request).ConfigureAwait(false);

                return(DacpUtility.GetItemsFromNodes(response.Nodes, itemGenerator, listKey).ToList());
            }
            catch (Exception)
            {
                return(new List <T>());
            }
        }
예제 #10
0
        public static IDacpList GetAlphaGroupedDacpList <T>(IEnumerable <DacpNode> nodes, Func <byte[], T> itemGenerator, out List <T> items, string listKey = DefaultListKey, bool useGroupMinimums = true)
        {
            var nodeList = nodes.ToList();

            items = GetItemsFromNodes(nodeList, itemGenerator, listKey).ToList();
            var headers = nodeList.FirstOrDefault(n => n.Key == "mshl");
            IEnumerable <DacpNode> headerNodes = null;

            if (headers != null)
            {
                headerNodes = DacpUtility.GetResponseNodes(headers.Value);
            }

            return(GetAlphaGroupedDacpList(items, headerNodes, useGroupMinimums));
        }
예제 #11
0
        private async Task <bool> GetServerCapabilitiesAsync()
        {
            DacpRequest request = new DacpRequest("/ctrl-int");

            request.IncludeSessionID = false;

            try
            {
                var response = await SendRequestAsync(request).ConfigureAwait(false);

                // Process response
                var mlcl  = DacpUtility.GetResponseNodes(response.Nodes.First(n => n.Key == "mlcl").Value);
                var nodes = DacpNodeDictionary.Parse(mlcl.First(n => n.Key == "mlit").Value);

                if (nodes.ContainsKey("ceSX"))
                {
                    Int64 ceSX = nodes.GetLong("ceSX");

                    // Bit 0: Supports Play Queue
                    if ((ceSX & (1 << 0)) != 0)
                    {
                        ServerSupportsPlayQueue = true;
                    }

                    // Bit 1: iTunes Radio? Appeared in iTunes 11.1.2 with the iTunes Radio DB.
                    // Apple's Remote for iOS doesn't seem to use this bit to determine whether iTunes Radio is available.
                    // Instead, it looks for an iTunes Radio database and checks whether it has any containers.

                    // Bit 2: Genius Shuffle Enabled/Available
                    if ((ceSX & (1 << 2)) != 0)
                    {
                        ServerSupportsGeniusShuffle = true;
                    }
                }
            }
            catch { return(false); }
            return(true);
        }
예제 #12
0
        private async Task <bool> GetServerInfoAsync()
        {
            DacpRequest request = new DacpRequest("/server-info");

            request.IncludeSessionID = false;

            try
            {
                var response = await SendRequestAsync(request).ConfigureAwait(false);

                // Process response
                ServerVersion = response.HTTPResponse.Headers.GetValueOrDefault("DAAP-Server");

                var nodes = DacpNodeDictionary.Parse(response.Nodes);
                ServerName = nodes.GetString("minm");
                //ServerVersion = nodes.GetInt("aeSV");
                //ServerDMAPVersion = nodes.GetInt("mpro");
                //ServerDAAPVersion = nodes.GetInt("apro");

                // MAC addresses
                if (nodes.ContainsKey("msml"))
                {
                    List <string> macAddresses = new List <string>();
                    var           addressNodes = DacpUtility.GetResponseNodes(nodes["msml"]).Where(n => n.Key == "msma").Select(n => n.Value);
                    foreach (var addressNode in addressNodes)
                    {
                        var address = BitConverter.ToInt64(addressNode, 0);
                        address = address >> 16;
                        macAddresses.Add(address.ToString("X12"));
                    }
                    ServerMacAddresses = macAddresses.ToArray();
                }
            }
            catch { return(false); }
            return(true);
        }
예제 #13
0
 public static DacpNodeDictionary Parse(byte[] data)
 {
     return(Parse(DacpUtility.GetResponseNodes(data)));
 }
예제 #14
0
 public static string QueryEncodeString(string input)
 {
     return(Uri.EscapeDataString(DacpUtility.EscapeSingleQuotes(input)));
 }