private static async Task <List <AppleFeedback> > _feedbackReadResponse(Internal.APNSConnection connection)
        {
            var rtn = new List <AppleFeedback>();

            byte[] msg;

            while ((msg = await connection.Receive(6, true)) != null)
            {
                var timestamp   = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
                var deviceToken = await connection.Receive((msg[4] << 8) | (msg[5]), false);

                rtn.Add(new AppleFeedback(timestamp, deviceToken));
            }

            return(rtn);
        }
        public async Task <List <AppleFeedback> > Feedback()
        {
            Task <List <AppleFeedback> > readTask;

            using (var connection = new Internal.APNSConnection()) {
                await connection.Connect(Development? "feedback.sandbox.push.apple.com" : "feedback.push.apple.com", 2196, ClientCertificate, 30 * 1000);

                readTask = _feedbackReadResponse(connection);

                using (CancellationTokenSource cts = new CancellationTokenSource(15000))
                    await Task.WhenAny(readTask, Task.Delay(-1, cts.Token));
            }

            await readTask;

            return(readTask.Result);
        }
        private void                        _close()
        {
            lock (_lockObject) {
                _isAvailable = false;

                if (_connection != null)
                {
                    _connection.Dispose();
                    _connection = null;
                }

                if (_connectionTimer != null)
                {
                    _connectionTimer.Dispose();
                    _connectionTimer = null;
                }
            }
        }
        public async Task                        ConnectAsync()
        {
            _connection = new APNSConnection();
            string hostname = Config.Development ? "gateway.sandbox.push.apple.com" : "gateway.push.apple.com";

            try {
                await _connection.Connect(hostname, 2195, Config.ClientCertificate, 30 * 1000);
            }
            catch (Exception err) {
                throw new PushNotificationConnectionException("connect(" + hostname + "): failed.", err);
            }

            lock (_lockObject) {
                _isAvailable   = _connection.Connected;
                _notifications = new List <Notification>(Config.RecyleCount);

                if (_isAvailable)
                {
                    _receiveTask     = Task.Run(_receiveResponceAsync);
                    _connectionTimer = new Timer(_connectionTimer_callback, null, Config.RecyleTimout, Timeout.Infinite);
                }
            }
        }