using Npgsql; using NpgsqlTypes; using skyscraper5.Docsis.MacManagement; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; namespace skyscraper5.Data.PostgreSql { partial class PostgresqlDataStore { private HashSet> knownDocsisUpstreams; public bool TestForDocsisUpstreamChannel(PhysicalAddress mmmSource, uint mmmFrequency, int currentLocation) { if (knownDocsisUpstreams == null) knownDocsisUpstreams = new HashSet>(); Tuple tuple = new Tuple(currentLocation, mmmFrequency); if (knownDocsisUpstreams.Contains(tuple)) return true; using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString())) { connection.Open(); NpgsqlCommand command = connection.CreateCommand(); command.CommandText = "SELECT dateadded FROM docsis_upstream_channel WHERE location = @loc AND frequency=@freq"; command.Parameters.AddWithValue("@loc", NpgsqlDbType.Integer, currentLocation); command.Parameters.AddWithValue("@freq", NpgsqlDbType.Integer, (int)mmmFrequency); NpgsqlDataReader reader = command.ExecuteReader(); bool result = reader.Read(); if (result) { knownDocsisUpstreams.Add(tuple); } reader.Close(); connection.Close(); return result; } } public void StoreDocsisUpstreamChannel(UpstreamChannelDescriptor mmm, int currentLocation) { using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString())) { connection.Open(); NpgsqlTransaction transaction = connection.BeginTransaction(); NpgsqlCommand command = connection.CreateCommand(); command.CommandText = "INSERT INTO docsis_upstream_channel " + "VALUES (DEFAULT, DEFAULT, @loc, @freq, @upstreamChannelId, @configChangeCount, @minislotSize, @downstreamChannelId, @randomSeed, @symbolsInOfdmaFrame, " + "@centerFrequencyOfSubcarrier, @subcarrierSpacing, @ofdmaRolloffPeriodSize, @ofdmaCyclicPrefixSize, @ofdmaTimesnapSnapshotDivide, @ofdmaTimestampSnapshot, " + "@ucdChangeIndicator, @sCdmaMode, @preamblePattern, @modulationRate) RETURNING ss5_serial"; command.Parameters.AddWithValue("@loc", NpgsqlDbType.Integer, currentLocation); command.Parameters.AddWithValue("@freq", NpgsqlDbType.Integer, (int)mmm.Frequency); command.Parameters.AddWithValue("@upstreamChannelId", NpgsqlDbType.Integer, mmm.UpstreamChannelID); command.Parameters.AddWithValue("@configChangeCount", NpgsqlDbType.Integer, mmm.ConfigurationChangeCount); command.Parameters.AddWithValue("@minislotSize", NpgsqlDbType.Integer, mmm.MinislotSize); command.Parameters.AddWithValue("@downstreamChannelId", NpgsqlDbType.Integer, mmm.DownstreamChannelId); command.Parameters.AddWithValue("@randomSeed", NpgsqlDbType.Integer, (int)mmm.RandomizationSeed); command.Parameters.AddWithValue("@symbolsInOfdmaFrame", NpgsqlDbType.Integer, mmm.SymbolsInOfdmaFrame); command.Parameters.AddWithValue("@centerFrequencyOfSubcarrier", NpgsqlDbType.Bigint, mmm.CenterFrequencyOfSubcarrier0); command.Parameters.AddWithValue("@subcarrierSpacing", NpgsqlDbType.Integer, mmm.SubcarrierSpacing); command.Parameters.AddWithValue("@ofdmaRolloffPeriodSize", NpgsqlDbType.Integer, mmm.OfdmaRolloffPeriodSize); command.Parameters.AddWithValue("@ofdmaCyclicPrefixSize", NpgsqlDbType.Integer, mmm.OfdmaCyclicPrefixSize); command.Parameters.AddWithValue("@ofdmaTimesnapSnapshotDivide", NpgsqlDbType.Integer, mmm.OfdmaTimestampSnapshotDivideBy20); command.Parameters.AddWithValue("@ofdmaTimestampSnapshot", NpgsqlDbType.Integer, mmm.OfdmaTimestampSnapshot); command.Parameters.AddWithValue("@ucdChangeIndicator", NpgsqlDbType.Integer, mmm.UcdChangeIndicator?.GetRawValue()); command.Parameters.AddWithValue("@sCdmaMode", NpgsqlDbType.Boolean, mmm.S_CDMAMode); command.Parameters.AddWithValue("@preamblePattern", NpgsqlDbType.Bytea, mmm.PreamblePattern); command.Parameters.AddWithValue("@modulationRate", NpgsqlDbType.Integer, mmm.ModulationRate); SetNulls(command); NpgsqlDataReader dataReader = command.ExecuteReader(); dataReader.Read(); int ss5serial = dataReader.GetInt32(0); dataReader.Close(); command.Dispose(); if (mmm.BurstDescriptors != null && mmm.BurstDescriptors.Count > 0) { InsertDocsisUpstreamChannelBurstDescriptors(connection, ss5serial, mmm.BurstDescriptors); } if (mmm.SubcarrierExclusionBand != null && mmm.SubcarrierExclusionBand.Length > 0) { throw new NotImplementedException(); } transaction.Commit(); connection.Close(); } } private void InsertDocsisUpstreamChannelBurstDescriptors(NpgsqlConnection connection, int channelSs5serial, List burstDescriptors) { NpgsqlCommand cmd = connection.CreateCommand(); cmd.CommandText = "insert into docsis_upstream_channel_burst_descriptors VALUES (DEFAULT, @related_channel, DEFAULT, @subcarriers_fine_ranging, " + "@ofdma_broadcast_ir_starting_power_level_increase, @ofdma_broadcast_ir_starting_power_level, @subcarriers_initial_ranging, @preamble_type, " + "@rs_interleaver_block_size, @rs_interleaver_depth, @scrambler, @last_codeword_length, @guard_time_size, @maximum_burst_size, @scrambler_seed, " + "@fec_codeword_information_bytes, @fec_error_correction, @preamble_value_offset, @preamble_length, @differential_encoding, @modulation_type, @interval_usage_code) RETURNING ss5_serial"; cmd.Parameters.AddWithValue("@related_channel", NpgsqlDbType.Integer, channelSs5serial); cmd.Parameters.Add("@subcarriers_fine_ranging", NpgsqlDbType.Integer); cmd.Parameters.Add("@ofdma_broadcast_ir_starting_power_level_increase", NpgsqlDbType.Double); cmd.Parameters.Add("@ofdma_broadcast_ir_starting_power_level", NpgsqlDbType.Double); cmd.Parameters.Add("@subcarriers_initial_ranging", NpgsqlDbType.Integer); cmd.Parameters.Add("@preamble_type", NpgsqlDbType.Integer); cmd.Parameters.Add("@rs_interleaver_block_size", NpgsqlDbType.Integer); cmd.Parameters.Add("@rs_interleaver_depth", NpgsqlDbType.Integer); cmd.Parameters.Add("@scrambler", NpgsqlDbType.Boolean); cmd.Parameters.Add("@last_codeword_length", NpgsqlDbType.Integer); cmd.Parameters.Add("@guard_time_size", NpgsqlDbType.Integer); cmd.Parameters.Add("@maximum_burst_size", NpgsqlDbType.Integer); cmd.Parameters.Add("@scrambler_seed", NpgsqlDbType.Integer); cmd.Parameters.Add("@fec_codeword_information_bytes", NpgsqlDbType.Integer); cmd.Parameters.Add("@fec_error_correction", NpgsqlDbType.Integer); cmd.Parameters.Add("@preamble_value_offset", NpgsqlDbType.Integer); cmd.Parameters.Add("@preamble_length", NpgsqlDbType.Integer); cmd.Parameters.Add("@differential_encoding", NpgsqlDbType.Boolean); cmd.Parameters.Add("@modulation_type", NpgsqlDbType.Integer); cmd.Parameters.Add("@interval_usage_code", NpgsqlDbType.Integer); foreach (UpstreamChannelDescriptor.BurstDescriptor bd in burstDescriptors) { cmd.Parameters["@subcarriers_fine_ranging"].Value = bd.SubcarriersFineRanging; cmd.Parameters["@ofdma_broadcast_ir_starting_power_level_increase"].Value = bd.OfdmaBroadcastIrStartingPowerLevelIncrease; cmd.Parameters["@ofdma_broadcast_ir_starting_power_level"].Value = bd.OfdmaBroadcastIrStartingPowerLevel; cmd.Parameters["@subcarriers_initial_ranging"].Value = bd.SubcarriersInitialRanging; cmd.Parameters["@preamble_type"].Value = (int)bd.PreambleType; cmd.Parameters["@rs_interleaver_block_size"].Value = (int)bd.RsInterleaverBlockSize; cmd.Parameters["@rs_interleaver_depth"].Value = bd.RsInterleaverDepth; cmd.Parameters["@scrambler"].Value = bd.Scrambler; cmd.Parameters["@last_codeword_length"].Value = (int)bd.LastCodewordLength; cmd.Parameters["@guard_time_size"].Value = bd.GuardTimeSize; cmd.Parameters["@maximum_burst_size"].Value = bd.MaximumBurstSize; cmd.Parameters["@scrambler_seed"].Value = bd.ScramblerSeed; cmd.Parameters["@fec_codeword_information_bytes"].Value = bd.FecCodewordInformationBytes; cmd.Parameters["@fec_error_correction"].Value = bd.FecErrorCorrection; cmd.Parameters["@preamble_value_offset"].Value = (int)bd.PreambleValueOffset; cmd.Parameters["@preamble_length"].Value = (int)bd.PreambleLength; cmd.Parameters["@differential_encoding"].Value = bd.DifferentialEncoding; cmd.Parameters["@modulation_type"].Value = (int)bd.ModulationType; cmd.Parameters["@interval_usage_code"].Value = bd.IntervalUsageCode; SetNulls(cmd); NpgsqlDataReader dataReader = cmd.ExecuteReader(); dataReader.Read(); int ourSerial = dataReader.GetInt32(0); dataReader.Close(); if (bd.OfdmaDataProfiles != null && bd.OfdmaDataProfiles.Length > 0) { throw new NotImplementedException(); } } cmd.Dispose(); } private HashSet _knownDocsisParticipants; public void StoreDocsisParticipant(PhysicalAddress pa, int currentLocation) { if (_knownDocsisParticipants == null) _knownDocsisParticipants = new HashSet(); if (_knownDocsisParticipants.Contains(pa)) return; using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString())) { connection.Open(); NpgsqlCommand command = connection.CreateCommand(); command.CommandText = "SELECT dateadded FROM docsis_participants WHERE physicalAddr=@mac"; command.Parameters.AddWithValue("@mac", NpgsqlDbType.MacAddr, pa); NpgsqlDataReader reader = command.ExecuteReader(); if (reader.Read()) { _knownDocsisParticipants.Add(pa); connection.Close(); return; } reader.Close(); command.Dispose(); command = connection.CreateCommand(); command.CommandText = "INSERT INTO docsis_participants (location,physicalAddr) VALUES (@loc,@mac)"; command.Parameters.AddWithValue("@loc", NpgsqlDbType.Integer, currentLocation); command.Parameters.AddWithValue("@mac", NpgsqlDbType.MacAddr, pa); command.ExecuteNonQuery(); _knownDocsisParticipants.Add(pa); command.Dispose(); connection.Close(); } } private HashSet> _knownDownstreamChannels; public bool TestForDocsisDownstreamChannel(PhysicalAddress physicalAddress, MacDomainDescriptor.DownstreamActiveChannel downstreamActiveChannel, int currentLocation) { if (_knownDownstreamChannels == null) _knownDownstreamChannels = new HashSet>(); Tuple currentTuple = new Tuple(currentLocation, downstreamActiveChannel.Frequency.Value); if (_knownDownstreamChannels.Contains(currentTuple)) return true; using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString())) { connection.Open(); NpgsqlCommand command = connection.CreateCommand(); command.CommandText = "SELECT dateadded FROM docsis_downstream_channel WHERE location = @location AND frequency = @frequency"; command.Parameters.AddWithValue("@location", NpgsqlDbType.Integer, currentLocation); command.Parameters.AddWithValue("@frequency", NpgsqlDbType.Bigint, (long)downstreamActiveChannel.Frequency); NpgsqlDataReader dataReader = command.ExecuteReader(); bool result = dataReader.Read(); if (result) _knownDownstreamChannels.Add(currentTuple); dataReader.Close(); connection.Close(); return result; } } public void StoreDocsisDownstreamChannel(PhysicalAddress physicalAddress, MacDomainDescriptor.DownstreamActiveChannel downstreamActiveChannel, int currentLocation) { using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString())) { connection.Open(); NpgsqlCommand command = connection.CreateCommand(); command.CommandText = "insert into docsis_downstream_channel VALUES (DEFAULT, DEFAULT, @physical_address, @location, @frequency, @tukey_raised_cosine_window, " + "@cyclic_prefix, @khz_subcarrier_spacing, @qam_fec_lock_recovery, @mdd_recovery, @qam_fec_lock_failure, @mdd_timeout, @primary_capable, @modulation_order, " + "@annex, @channel_id)"; command.Parameters.AddWithValue("@physical_address", NpgsqlDbType.MacAddr, physicalAddress); command.Parameters.AddWithValue("@location", NpgsqlDbType.Integer, currentLocation); command.Parameters.AddWithValue("@frequency", NpgsqlDbType.Bigint, (long)downstreamActiveChannel.Frequency); command.Parameters.AddWithValue("@tukey_raised_cosine_window", NpgsqlDbType.Integer, downstreamActiveChannel.TukeyRaisedCosineWindow); command.Parameters.AddWithValue("@cyclic_prefix", NpgsqlDbType.Integer, downstreamActiveChannel.CyclicPrefix); command.Parameters.AddWithValue("@khz_subcarrier_spacing", NpgsqlDbType.Boolean, downstreamActiveChannel._50khzSubcarrierSpacing); command.Parameters.AddWithValue("@qam_fec_lock_recovery", NpgsqlDbType.Boolean, downstreamActiveChannel.QamFecLockRecovery); command.Parameters.AddWithValue("@mdd_recovery", NpgsqlDbType.Boolean, downstreamActiveChannel.MddRecovery); command.Parameters.AddWithValue("@qam_fec_lock_failure", NpgsqlDbType.Boolean, downstreamActiveChannel.QamFecLockFailure); command.Parameters.AddWithValue("@mdd_timeout", NpgsqlDbType.Boolean, downstreamActiveChannel.MddTimeout); command.Parameters.AddWithValue("@primary_capable", NpgsqlDbType.Integer, (int)downstreamActiveChannel.PrimaryCapable); if (downstreamActiveChannel.ModulationOrder.HasValue) command.Parameters.AddWithValue("@modulation_order", NpgsqlDbType.Integer, (int)downstreamActiveChannel.ModulationOrder); else command.Parameters.AddWithValue("@modulation_order", NpgsqlDbType.Integer, DBNull.Value); if (downstreamActiveChannel.Annex.HasValue) command.Parameters.AddWithValue("@annex", NpgsqlDbType.Integer, (int)downstreamActiveChannel.Annex); else command.Parameters.AddWithValue("@annex", NpgsqlDbType.Integer, DBNull.Value); command.Parameters.AddWithValue("@channel_id", NpgsqlDbType.Integer, downstreamActiveChannel.ChannelId); SetNulls(command); command.ExecuteNonQuery(); command.Dispose(); connection.Close(); } } private HashSet> cmts_ips; public bool SetCmtsIp(PhysicalAddress arpHeaderSenderHardwareAddress, IPAddress arpHeaderSenderProtocolAddress) { if (cmts_ips == null) cmts_ips = new HashSet>(); Tuple currentTuple = new Tuple(arpHeaderSenderHardwareAddress, arpHeaderSenderProtocolAddress); if (cmts_ips.Contains(currentTuple)) return false; using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString())) { connection.Open(); NpgsqlCommand command = connection.CreateCommand(); command.CommandText = "UPDATE docsis_participants SET ip = @ip WHERE physicaladdr = @mac"; command.Parameters.AddWithValue("@ip", NpgsqlDbType.Inet, arpHeaderSenderProtocolAddress); command.Parameters.AddWithValue("@mac", NpgsqlDbType.MacAddr, arpHeaderSenderHardwareAddress); int rows = command.ExecuteNonQuery(); bool result = rows > 0; if (result) cmts_ips.Add(currentTuple); command.Dispose(); connection.Close(); return result; } } } }