public void addTunerInfo(Message tunerMessage)
 {
     lock (_data)
     {
         string channelID = "" + tunerMessage.getInt("channelId");
         if (_data.ContainsKey(channelID))
         {
             _data.Remove(channelID);
         }
         _data.Add(channelID, tunerMessage);
     }
 }
 public void autorecEntryAdd(Message message)
 {
     string id = message.getString("id");
     lock (_data)
     {
         if (_data.ContainsKey(id))
         {
             _logger.Info("[TVHclient] AutorecDataHelper.autorecEntryAdd id already in database - skip!" + message.ToString());
             return;
         }
         _data.Add(id, message);
     }
 }
        public void Add(Message message)
        {
            if (_tunerDataHelper != null)
            {
                // TVHeadend don't send the information we need
                // _tunerDataHelper.addTunerInfo(message);
            }

            lock (_data)
            {
                try
                {
                    int channelID = message.getInt("channelId");
                    if (_data.ContainsKey(channelID))
                    {
                        Message storedMessage = _data[channelID];
                        if (storedMessage != null)
                        {
                            foreach (KeyValuePair<string, object> entry in message)
                            {
                                if (storedMessage.containsField(entry.Key))
                                {
                                    storedMessage.removeField(entry.Key);
                                }
                                storedMessage.putField(entry.Key, entry.Value);
                            }
                        }
                        else
                        {
                            _logger.Error("[TVHclient] ChannelDataHelper: update for channelID '" + channelID + "' but no initial data found!");
                        }
                    }
                    else
                    {
                        if (message.containsField("channelNumber") && message.getInt("channelNumber") > 0) // use only channels with number > 0
                        {
                            _data.Add(channelID, message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error("[TVHclient] ChannelDataHelper.Add caught exception: " + ex.Message + "\nMessage=" + message);
                }
            }
        }
        private static Message deserializeBinary(byte[] messageData)
        {
            byte type, namelen;
            long datalen;

            Message msg = new Message();
            int cnt = 0;

            ByteBuffer buf = new ByteBuffer(messageData);
            while (buf.hasRemaining())
            {
                type = buf.get();
                namelen = buf.get();
                datalen = uIntToLong(buf.get(), buf.get(), buf.get(), buf.get());

                if (buf.Length() < namelen + datalen)
                {
                    throw new IOException("Buffer limit exceeded");
                }

                //Get the key for the map (the name)
                string name = null;
                if (namelen == 0)
                {
                    name = Convert.ToString(cnt++);
                }
                else
                {
                    byte[] bName = new byte[namelen];
                    buf.get(bName);
                    name = NewString(bName);
                }

                //Get the actual content
                object obj = null;
                byte[] bData = new byte[datalen];
                buf.get(bData);

                switch (type)
                {
                    case HMF_STR:
                        {
                            obj = NewString(bData);
                            break;
                        }
                    case HMF_BIN:
                        {
                            obj = bData;
                            break;
                        }
                    case HMF_S64:
                        {
                            obj = toBigInteger(bData);
                            break;
                        }
                    case HMF_MAP:
                        {
                            obj = deserializeBinary(bData);
                            break;
                        }
                    case HMF_LIST:
                        {
                            obj = new List<object>(deserializeBinary(bData)._dict.Values);
                            break;
                        }
                    default:
                        throw new IOException("Unknown data type");
                }
                msg.putField(name, obj);
            }
            return msg;
        }
 public void autorecEntryDelete(Message message)
 {
     string id = message.getString("id");
     lock (_data)
     {
         _data.Remove(id);
     }
 }
 public void autorecEntryUpdate(Message message)
 {
     string id = message.getString("id");
     lock (_data)
     {
         Message oldMessage = _data[id];
         if (oldMessage == null)
         {
             _logger.Info("[TVHclient] AutorecDataHelper.autorecEntryAdd id not in database - skip!" + message.ToString());
             return;
         }
         foreach (KeyValuePair<string, object> entry in message)
         {
             if (oldMessage.containsField(entry.Key))
             {
                 oldMessage.removeField(entry.Key);
             }
             oldMessage.putField(entry.Key, entry.Value);
         }
     }
 }
 public void SendMessage(Message message, IResponseHandler responseHandler)
 {
     ensureConnection();
     _htsConnection.sendMessage(message, responseHandler);
 }
        public void OnMessage(Message response)
        {
            if (response != null)
            {
                switch (response.Method)
                {
                    case "tagAdd":
                    case "tagUpdate":
                    case "tagDelete":
                        //_logger.Fatal("[TVHclient] tad add/update/delete" + response.ToString());
                        break;

                    case "channelAdd":
                    case "channelUpdate":
                        _channelDataHelper.Add(response);
                        break;

                    case "dvrEntryAdd":
                        _dvrDataHelper.dvrEntryAdd(response);
                        break;
                    case "dvrEntryUpdate":
                        _dvrDataHelper.dvrEntryUpdate(response);
                        break;
                    case "dvrEntryDelete":
                        _dvrDataHelper.dvrEntryDelete(response);
                        break;

                    case "autorecEntryAdd":
                        _autorecDataHelper.autorecEntryAdd(response);
                        break;
                    case "autorecEntryUpdate":
                        _autorecDataHelper.autorecEntryUpdate(response);
                        break;
                    case "autorecEntryDelete":
                        _autorecDataHelper.autorecEntryDelete(response);
                        break;

                    case "eventAdd":
                    case "eventUpdate":
                    case "eventDelete":
                        // should not happen as we don't subscribe for this events.
                        break;

                    //case "subscriptionStart":
                    //case "subscriptionGrace":
                    //case "subscriptionStop":
                    //case "subscriptionSkip":
                    //case "subscriptionSpeed":
                    //case "subscriptionStatus":
                    //    _logger.Fatal("[TVHclient] subscription events " + response.ToString());
                    //    break;

                    //case "queueStatus":
                    //    _logger.Fatal("[TVHclient] queueStatus event " + response.ToString());
                    //    break;

                    //case "signalStatus":
                    //    _logger.Fatal("[TVHclient] signalStatus event " + response.ToString());
                    //    break;

                    //case "timeshiftStatus":
                    //    _logger.Fatal("[TVHclient] timeshiftStatus event " + response.ToString());
                    //    break;

                    //case "muxpkt": // streaming data
                    //    _logger.Fatal("[TVHclient] muxpkt event " + response.ToString());
                    //    break;

                    case "initialSyncCompleted":
                        _initialLoadFinished = true;
                        break;

                    default:
                        //_logger.Fatal("[TVHclient] Method '" + response.Method + "' not handled in LiveTvService.cs");
                        break;
                }
            }
        }
        public Boolean authenticate(String username, String password)
        {
            _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: start");

            Message helloMessage = new Message();
            helloMessage.Method = "hello";
            helloMessage.putField("clientname", _clientName);
            helloMessage.putField("clientversion", _clientVersion);
            helloMessage.putField("htspversion", Message.HTSP_VERSION);
            helloMessage.putField("username", username);

            LoopBackHandler LoopBackHandler = new LoopBackHandler();
            sendMessage(helloMessage, LoopBackHandler);
            Message helloResponse = LoopBackHandler.getResponse();
            if (helloResponse != null)
            {
                if (helloResponse.containsField("htspversion"))
                {
                    _serverProtocolVersion = helloResponse.getInt("htspversion");
                }
                else
                {
                    _serverProtocolVersion = -1;
                    _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'htspversion' - htsp wrong implemented on tvheadend side.");
                }

                if (helloResponse.containsField("servername"))
                {
                    _servername = helloResponse.getString("servername");
                }
                else
                {
                    _servername = "n/a";
                    _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'servername' - htsp wrong implemented on tvheadend side.");
                }

                if (helloResponse.containsField("serverversion"))
                {
                    _serverversion = helloResponse.getString("serverversion");
                }
                else
                {
                    _serverversion = "n/a";
                    _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'serverversion' - htsp wrong implemented on tvheadend side.");
                }

                byte[] salt = null;
                if (helloResponse.containsField("challenge"))
                {
                    salt = helloResponse.getByteArray("challenge");
                }
                else
                {
                    salt = new byte[0];
                    _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'challenge' - htsp wrong implemented on tvheadend side.");
                }

                byte[] digest = Sha1.GenerateSaltedSHA1(password, salt);
                Message authMessage = new Message();
                authMessage.Method = "authenticate";
                authMessage.putField("username", username);
                authMessage.putField("digest", digest);
                sendMessage(authMessage, LoopBackHandler);
                Message authResponse = LoopBackHandler.getResponse();
                if (authResponse != null)
                {
                    Boolean auth = authResponse.getInt("noaccess", 0) != 1;
                    if (auth)
                    {
                        Message getDiskSpaceMessage = new Message();
                        getDiskSpaceMessage.Method = "getDiskSpace";
                        sendMessage(getDiskSpaceMessage, LoopBackHandler);
                        Message diskSpaceResponse = LoopBackHandler.getResponse();
                        if (diskSpaceResponse != null)
                        {
                            long freeDiskSpace = -1;
                            long totalDiskSpace = -1;
                            if (diskSpaceResponse.containsField("freediskspace"))
                            {
                                freeDiskSpace = diskSpaceResponse.getLong("freediskspace") / BytesPerGiga;
                            }
                            else
                            {
                                _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: getDiskSpace don't deliver required field 'freediskspace' - htsp wrong implemented on tvheadend side.");
                            }
                            if (diskSpaceResponse.containsField("totaldiskspace"))
                            {
                                totalDiskSpace = diskSpaceResponse.getLong("totaldiskspace") / BytesPerGiga;
                            }
                            else
                            {
                                _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: getDiskSpace don't deliver required field 'totaldiskspace' - htsp wrong implemented on tvheadend side.");
                            }

                            _diskSpace = freeDiskSpace + "GB / " + totalDiskSpace + "GB";
                        }

                        Message enableAsyncMetadataMessage = new Message();
                        enableAsyncMetadataMessage.Method = "enableAsyncMetadata";
                        sendMessage(enableAsyncMetadataMessage, null);
                    }

                    _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: authenticated = " + auth);
                    return auth;
                }
            }
            _logger.Error("[TVHclient] HTSConnectionAsync.authenticate: no hello response");
            return false;
        }
        public void sendMessage(Message message, IResponseHandler responseHandler)
        {
            // loop the sequence number
            if (_seq == int.MaxValue)
            {
                _seq = int.MinValue;
            }
            else
            {
                _seq++;
            }

            // housekeeping verry old response handlers
            if (_responseHandlers.ContainsKey(_seq))
            {
                _responseHandlers.Remove(_seq);
            }

            message.putField("seq", _seq);
            _messagesForSendQueue.Enqueue(message);
            _responseHandlers.Add(_seq, responseHandler);
        }