private static bool EnsureValidCsa(IntPtr context, ec_slave_info_t[] newSlaves, ec_slave_info_t[] referenceSlaves) { // UPDATE: first step ('isValid') is skipped as CSA is now generated randomly. This function returns now a boolean to indicate success. // // // // Idea: // 1. isValid: select all slaves whose CSA is greater than zero but smaller than the CSA-base // // 2. hasUniqueCsa: select all slaves with overall unique CSA (both lists) // // 3. toBeProtected: select all slaves of new list that are distinct (comparison of CSA is not sufficient) and have counterpart in reference list // -> throw out all slaves where reference CSA is not unique // // 4. Combination: isValid & (hasUniqueCsa | toBeProtected) // // ## EXAMPLE ## * -> indicates that new slave is identical to referenced slave // // CSA base : 7 // // reference slave CSAs: 1 1 2 3 // new slave CSAs: 1*| 2 2*| 3 3* 3* | 4 | 9 | 0 // // // hasRef: 1 | 0 1 | 0 1 1 | 0 | 0 | 0 // isDistinct: 1 | 1 1 | 1 0 0 | 1 | 1 | 1 // hasUniqueCsa_ref: 0 | 1 1 | 1 1 1 | 0 | 0 | 0 // =============================== // toBeProtected: 0 | 0 1 | 0 0 0 | 0 | 0 | 0 // // // new slave CSAs: 1*| 2 2*| 3 3* 3* | 4 | 9 | 0 // _______________________________ // isValid: 1 | 1 1 | 1 1 1 | 1 | 0 | 0 // hasUniqueCsa: 0 | 0 1 | 0 0 0 | 1 | 1 | 1 // toBeProtected: 0 | 0 1 | 0 0 0 | 0 | 0 | 0 // =============================== // result: 0 | 0 1 | 0 0 0 | 1 | 0 | 0 // // 5. take all slaves whose result is '0' and update their CSA // result: 7 | 8 2 | 9 10 11 | 4 | 12| 13 //// reference //var reference1 = new ec_slave_info_t() { csa = 1, manufacturer = 2, productCode = 2, revision = 2 }; // 1 //var reference2 = new ec_slave_info_t() { csa = 1, manufacturer = 3, productCode = 2, revision = 2 }; // 1 //var reference3 = new ec_slave_info_t() { csa = 2, manufacturer = 2, productCode = 2, revision = 2 }; // 2 //var reference4 = new ec_slave_info_t() { csa = 3, manufacturer = 2, productCode = 2, revision = 2 }; // 3 //var reference = new ec_slave_info_t[] { reference1, reference2, reference3, reference4 }; //// new //var new1 = new ec_slave_info_t() { csa = 1, manufacturer = 2, productCode = 2, revision = 2 }; // 1 //var new2 = new ec_slave_info_t() { csa = 2, manufacturer = 2, productCode = 3, revision = 2 }; // 2 //var new3 = new ec_slave_info_t() { csa = 2, manufacturer = 2, productCode = 2, revision = 2 }; // 2 //var new4 = new ec_slave_info_t() { csa = 3, manufacturer = 7, productCode = 2, revision = 2 }; // 3 //var new5 = new ec_slave_info_t() { csa = 3, manufacturer = 2, productCode = 2, revision = 2 }; // 3 //var new6 = new ec_slave_info_t() { csa = 3, manufacturer = 2, productCode = 2, revision = 2 }; // 3 //var new7 = new ec_slave_info_t() { csa = 4, manufacturer = 2, productCode = 2, revision = 2 }; // 4 //var new8 = new ec_slave_info_t() { csa = 9, manufacturer = 2, productCode = 2, revision = 2 }; // 9 //var new9 = new ec_slave_info_t() { csa = 0, manufacturer = 2, productCode = 2, revision = 2 }; // 0 //var newset = new ec_slave_info_t[] { new1, new2, new3, new4, new5, new6, new7, new8, new9 }; //Settings.Default.CsaBase = 7; //SoemWrapper.ValidateCsa(newset, reference); var totalSlaves = newSlaves.Concat(referenceSlaves).ToArray(); var totalSlavesCsaDistinct = totalSlaves.Select(x => x.csa).TrueDistinct().ToArray(); var newSlavesDistinct = newSlaves.TrueDistinct().ToArray(); var referenceSlavesCsaDistinct = referenceSlaves.Select(x => x.csa).TrueDistinct().ToArray(); var hasCsaChanged = false; for (int i = 0; i < newSlaves.Count(); i++) { ec_slave_info_t newSlave = newSlaves[i]; // 1. - isValid var isValid = true; // isValid = newSlave.csa > 0 && newSlave.csa < originalCsaBase; // 2. - hasUniqueCsa var hasUniqueCsa = totalSlavesCsaDistinct.Contains(newSlave.csa); // 3. - toBeProtected // => hasRef var referenceSlave = referenceSlaves.FirstOrDefault(x => x.csa == newSlave.csa); var hasRef = referenceSlave.csa == newSlave.csa && referenceSlave.manufacturer == newSlave.manufacturer && referenceSlave.productCode == newSlave.productCode && referenceSlave.revision == newSlave.revision; // => isDistinct var isDistinct = newSlavesDistinct.Contains(newSlave); // => hasUniqueCsa_ref var hasUniqueCsa_ref = referenceSlavesCsaDistinct.Contains(newSlave.csa); // => toBeProtected var toBeProtected = hasRef && isDistinct && hasUniqueCsa_ref; // 4. Combination if (i > 0 && !(isValid && (hasUniqueCsa || toBeProtected))) { var csaValue = (ushort)_random.Next(1, ushort.MaxValue); EcHL.UpdateCsa(context, newSlaves.ToList().IndexOf(newSlave), csaValue); newSlave.csa = csaValue; newSlaves[i] = newSlave; hasCsaChanged = true; } } return(hasCsaChanged); }