static void MacBase_OnNeighborChange(IMAC macInstance, DateTime time) { var neighborList = MACBase.NeighborListArray(); macInstance.NeighborList(neighborList); PrintNeighborList("\t\tNeighbor list CHANGE for Node [" + _macBase.MACRadioObj.RadioAddress + "]: ", neighborList); }
/// <summary> /// Custom constructor. /// </summary> /// <param name="digest">Hash functon.</param> /// <param name="mac">MAC function.</param> /// <param name="iteration">Loop count.</param> public PBKDF2(IHash digest, IMAC mac, int iteration = 1000) { if (digest == null) { this._HashFunction = new Blake2b(512); } else { this._HashFunction = digest; } if (mac == null) { this._MACFunction = new HMAC(this._HashFunction); } else { this._MACFunction = mac; } if (iteration <= 0) { this._Iteration = 1000; } else { this._Iteration = iteration; } }
public static string MacInfo(IMAC imacInstance) { var info = "MAC Type: " + imacInstance.GetType() + ", Channel: " + imacInstance.MACRadioObj.Channel + ", Power: " + imacInstance.MACRadioObj.TxPower + ", Radio Address: " + imacInstance.MACRadioObj.RadioAddress + ", Radio Type: " + imacInstance.MACRadioObj.RadioName + ", Neighbor Liveness Delay: " + imacInstance.NeighborLivenessDelay; return(info); }
private static void RadioReceive(IMAC macBase, DateTime receiveDateTime, Packet packet) { /* * t1: when the local node sent a request * t2: when a partner node received the request * t3: when the partner node sent a response * t4: when then local node received the response * * requset: "Request t1" * respond: "Respond t1 t2 t3" */ long recvTime = time2Long(receiveDateTime) + _offset; // could be t2 or t4 var msgByte = packet.Payload; var msgChar = Encoding.UTF8.GetChars(msgByte); var msgStr = new string(msgChar); ushort recvFromAddress = packet.Src; Debug.Print("\tReceived: \"" + msgStr + "\"" + " from " + packet.Src); if (msgStr.Length < HeadLength) { return; } if (msgStr.Substring(0, HeadLength) == HeaderRespond) { string payload = msgStr.Substring(HeaderRespond.Length); String[] timeStrings = payload.Split(' '); long t1, t2, t3, t4 = recvTime; try { t1 = long.Parse(timeStrings[0]); t2 = long.Parse(timeStrings[1]); t3 = long.Parse(timeStrings[2]); } catch { return; } _offsetSum += (t2 - t1 + t3 - t4) / 2; _numResponded++; } else if (msgStr.Substring(0, HeadLength) == HeaderRequest) { string t1Str = msgStr.Substring(HeaderRespond.Length); long t3 = getLocalTime(); string response = t1Str + " " + recvTime.ToString() + " " + t3.ToString(); RadioSend(response, recvFromAddress); } }
public static void PrintMessageReceived(IMAC imac, string toPrint) { const string stars = "****************** "; var pipe = imac as MACPipe; if (pipe != null) { Debug.Print("\n" + stars + toPrint + " Receive on pipe " + pipe.PayloadType); } else { Debug.Print("\n" + stars + toPrint + " Receive"); } }
public static void PrintMessageSent(IMAC imac, string toPrint) { const string hashes = "################## "; var pipe = imac as MACPipe; if (pipe != null) { Debug.Print("\n" + hashes + toPrint + " Sent on pipe " + pipe.PayloadType); } else { Debug.Print("\n" + hashes + toPrint + " Sent"); } }
/// <summary> /// Send a message to all neighbors /// </summary> /// <param name="mac"></param> /// <param name="message"></param> /// <param name="messageLength"></param> public static void Broadcast(IMAC mac, byte[] message, int messageLength) { var neighbors = MACBase.NeighborListArray(); mac.NeighborList(neighbors); #if !DBG_LOGIC PrintNeighborList(mac); #endif var pipe = mac as MACPipe; #if DBG_VERBOSE if (pipe != null) { PrintNumericVals("Broadcast (on MACPipe " + pipe.PayloadType + "): ", message, messageLength); } else { PrintNumericVals("Broadcast: ", message, messageLength); } #endif foreach (var theNeighbor in neighbors) { if (theNeighbor == 0) { continue; } var status = pipe.EnqueueToSend(theNeighbor, message, 0, (ushort)messageLength); #if DBG_VERBOSE if (status != NetOpStatus.S_Success) { Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Send status: " + status); } Debug.Print("\tSent to " + theNeighbor); #elif DBG_SIMPLE Debug.Print("\tSent to " + theNeighbor + ", status: " + status); #endif } }
private static bool TryGetNanoAlgorithm(IMAC referent, int macSize, out IMAC algorithm) { if (macSize == -1) { algorithm = referent; return(true); } else if (macSize == referent.BlockSize / 2) { algorithm = referent; return(true); } else if (macSize >= 8 && macSize <= referent.BlockSize && macSize % 8 == 0) { algorithm = new MAC(((MAC)referent).BlockAlgorithm, macSize); return(true); } else { algorithm = null; return(false); } }
/// <summary> /// Send a message to all neighbors - moved here from SystemGlobal /// </summary> /// <param name="mac"></param> /// <param name="message"></param> /// <param name="messageLength"></param> public static void BroadcastBeacon(IMAC mac, byte[] message, int messageLength) { var neighbors = MACBase.NeighborListArray(); mac.NeighborList(neighbors); #if !DBG_LOGIC SystemGlobal.PrintNeighborList(mac); #endif var pipe = mac as MACPipe; #if DBG_VERBOSE if (pipe != null) { PrintNumericVals("Broadcast (on MACPipe " + pipe.PayloadType + "): ", message, messageLength); } else { PrintNumericVals("Broadcast: ", message, messageLength); } #endif foreach (var theNeighbor in neighbors) { if (theNeighbor == 0) { continue; } var status = pipe.EnqueueToSend(theNeighbor, message, 0, (ushort)messageLength); if (pipe.IsMsgIDValid(status)) { // Update link metrics if (theNeighbor == Parent) { UpdateNumTriesInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for parent " + theNeighbor + "; new value = " + GetNumTriesInCurrentWindow_Parent()); #endif } else { byte cindex = CandidateTable.findIndex(theNeighbor); if (cindex < byte.MaxValue) { CandidateTable._candidateList[cindex].UpdateNumTriesInCurrentWindow(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for candidate " + theNeighbor + "; new value = " + CandidateTable._candidateList[cindex].GetNumTriesInCurrentWindow()); #endif } } #if DBG_VERBOSE if (status != NetOpStatus.S_Success) { Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Send status: " + status); } Debug.Print("\tSent to " + theNeighbor); #elif DBG_SIMPLE Debug.Print("\tSent to " + theNeighbor + ", status: " + status); #endif } } }
/// <summary> /// /// </summary> /// <param name="macBase"></param> /// <param name="dateTime"></param> private static void NetManagerStreamReceive(IMAC macBase, DateTime dateTime, Packet packet) { #if DBG_VERBOSE DebuggingSupport.PrintMessageReceived(macBase, "Net Manager"); #elif DBG_SIMPLE Debug.Print(""); #endif //Debug.Print("\ton " + packet.PayloadType); var rcvPayloadBytes = packet.Payload; //var payload = new string(Encoding.UTF8.GetChars(rcvPayloadBytes)); #if DBG_VERBOSE SystemGlobal.PrintNumericVals("Net Manager Rcv: ", rcvPayloadBytes); #elif DBG_SIMPLE Debug.Print(""); #endif switch ((NetManagerGlobal.MessageIds)rcvPayloadBytes[0]) { case NetManagerGlobal.MessageIds.Heartbeat: ushort originator; ushort numBeat; SystemGlobal.NodeTypes nodeType; ushort parent; byte TTL; NetManagerGlobal.MoteMessages.Parse.HeartBeat(rcvPayloadBytes, out originator, out numBeat, out nodeType, out parent, out TTL); // NetManagerGlobal.MoteMessages.Parse.HeartBeat(rcvPayloadBytes, out originator, out numBeat, out nodeType, out parent, out bestetx, out neighbors, out nbrStatus, out numSamplesRec, out numSyncSent, out avgRSSI, out ewrnp); // NetManagerGlobal.MoteMessages.Parse.HeartBeat(rcvPayloadBytes, out originator, out numBeat, out nodeType, out parent, out bestetx, out num_nbrs, out neighbors, out nbrStatus, out numSamplesRec, out numSyncSent, out avgRSSI, out ewrnp, out isAvailableForUpperLayers, out TTL); Debug.Print("\t>>> Heartbeat #" + numBeat + " from neighbor " + packet.Src + " by " + originator + " with TTL " + TTL); #if DBG_DIAGNOSTIC Debug.Print("Parent: " + parent); Debug.Print(""); #endif #if RELAY_NODE || CLIENT_NODE // If we're the originator of the message, or if (TTL-1) is 0, do not pass it on. if (originator == _netManagerPipe.MACRadioObj.RadioAddress || --TTL == 0) { return; } RoutingGlobal.AddChild(originator, packet.Src); #region Uncomment when not using scheduler // TODO: Uncomment lines when not using scheduler // If in a reset, do not forward TODO: Change this to "spray" if (RoutingGlobal._color == Color.Red) { #if DBG_VERBOSE Debug.Print("\tIn a Reset wave... not forwarded"); #endif return; } // If parent is available, pass it on if (RoutingGlobal.IsParent) { byte[] routedMsg = new byte[rcvPayloadBytes.Length]; var size = NetManagerGlobal.MoteMessages.Compose.Heartbeat(routedMsg, originator, numBeat, nodeType, parent, TTL); var status = RoutingGlobal.SendToParent(_netManagerPipe, routedMsg, size); if (status != 999) { RoutingGlobal.UpdateNumTriesInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for Parent " + RoutingGlobal.Parent + "; new value = " + RoutingGlobal.GetNumTriesInCurrentWindow_Parent()); #endif } else //Retry once { #if !DBG_LOGIC Debug.Print("Retrying packet"); #endif RoutingGlobal.CleanseCandidateTable(_netManagerPipe); Candidate tmpBest = CandidateTable.GetBestCandidate(false); NetManagerGlobal.TempParent = tmpBest.GetMacID(); status = NetManagerGlobal.SendToTempParent(_netManagerPipe, routedMsg, size); if (status != 999) { tmpBest.UpdateNumTriesInCurrentWindow(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for TempParent " + NetManagerGlobal.TempParent + "; new value = " + tmpBest.GetNumTriesInCurrentWindow()); #endif } } } #endregion #region unused // If parent is not available, broadcast it //{ // //var size = NetManagerGlobal.ComposeMessages.CreateHeartbeat(NetManagerGlobal.MsgBytes, _netManagerPipe.MACRadioObj.RadioAddress); // SystemGlobal.BroadcastBeacon(_netManagerPipe, rcvPayloadBytes, packet.Size); //} //if (payload.Substring(0, 9).Equals("Heartbeat")) //Relay heartbeats, generated hourly //{ // Debug.Print("\tReceived Heartbeat: " + payload.Substring(0, 9) + "; source: " + payload.Substring(9) + "; from neighbor: " + packet.Src); // if (RoutingGlobal.Parent == SystemGlobal.NoParent) // { // return; // } // var toSendByte = Encoding.UTF8.GetBytes(payload); // var status = _netManagerPipe.Send(RoutingGlobal.Parent, toSendByte, 0, (ushort)toSendByte.Length); // if (status != NetOpStatus.S_Success) // { // Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Send status: " + status); // } // SystemGlobal.PrintNumericVals("Net Manager Snd: ", toSendByte); // Debug.Print("Forwarded Heartbeat: " + payload.Substring(0, 9) + "; source: " + payload.Substring(9) + "; from Node: " + packet.Src + " to Node: " + RoutingGlobal.Parent); //} #endregion #endif #if BASE_STATION string msg = NetManagerGlobal.PCMessages.Compose.Heartbeat(originator, numBeat, nodeType, parent); try { _serialComm.Write(msg); #if DBG_VERBOSE Debug.Print("\n************ Heartbeat forwarded to PC " + msg.Substring(1, msg.Length - 2)); #endif } catch (Exception ex) { Debug.Print("SerialComm exception for Heartbeat message [" + msg + "]\n" + ex); } #endif break; default: throw new ArgumentOutOfRangeException(); } }
private static void OnSendStatus(IMAC macInstance, DateTime time, SendPacketStatus ACKStatus, uint transmitDestination, ushort index) { var pipe = macInstance as MACPipe; switch (ACKStatus) { case SendPacketStatus.SendACKed: #if DBG_DIAGNOSTIC Debug.Print("\t\tNet Manager: Retry queue length = " + _retriedPackets.Count); #endif #if !DBG_LOGIC Debug.Print("Heartbeat to " + transmitDestination.ToString() + " ACKed"); #endif // Update link metrics if ((ushort)transmitDestination == RoutingGlobal.Parent) { RoutingGlobal.UpdateNumReceivedInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numReceivedInCurrentWindow for parent " + transmitDestination + "; new value = " + RoutingGlobal.GetNumReceivedInCurrentWindow_Parent()); #endif } else { byte cindex = CandidateTable.findIndex((ushort)transmitDestination); if (cindex < byte.MaxValue) { CandidateTable._candidateList[cindex].UpdateNumReceivedInCurrentWindow(1); #if !DBG_LOGIC Debug.Print("Updated numReceivedInCurrentWindow for candidate " + transmitDestination + "; new value = " + CandidateTable._candidateList[cindex].GetNumReceivedInCurrentWindow()); #endif } } if (_retriedPackets.Contains(index)) // If this was a re-try, remove packet from queue { _retriedPackets.Remove(index); } break; case SendPacketStatus.SendNACKed: #if !DBG_LOGIC Debug.Print("Heartbeat to " + transmitDestination.ToString() + " NACKed"); #endif // Update link metrics if ((ushort)transmitDestination == RoutingGlobal.Parent) { RoutingGlobal.UpdateNumTriesInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for parent " + transmitDestination + "; new value = " + RoutingGlobal.GetNumTriesInCurrentWindow_Parent()); #endif } else { byte cindex = CandidateTable.findIndex((ushort)transmitDestination); if (cindex < byte.MaxValue) { CandidateTable._candidateList[cindex].UpdateNumTriesInCurrentWindow(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for candidate " + transmitDestination + "; new value = " + CandidateTable._candidateList[cindex].GetNumTriesInCurrentWindow()); #endif } } break; case SendPacketStatus.SendFailed: #if DBG_DIAGNOSTIC Debug.Print("\t\tNet Manager: Retry queue length = " + _retriedPackets.Count); #endif #if !DBG_LOGIC Debug.Print("Heartbeat to " + transmitDestination.ToString() + " failed"); #endif // Update link metrics if ((ushort)transmitDestination == RoutingGlobal.Parent) { RoutingGlobal.UpdateNumTriesInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for parent " + transmitDestination + "; new value = " + RoutingGlobal.GetNumTriesInCurrentWindow_Parent()); #endif } else { byte cindex = CandidateTable.findIndex((ushort)transmitDestination); if (cindex < byte.MaxValue) { CandidateTable._candidateList[cindex].UpdateNumTriesInCurrentWindow(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for candidate " + transmitDestination + "; new value = " + CandidateTable._candidateList[cindex].GetNumTriesInCurrentWindow()); #endif } } // Retry if (!_retriedPackets.Contains(index) && RoutingGlobal._color == Color.Green) // If packet not there, enqueue it and retry it once { RoutingGlobal.CleanseCandidateTable(pipe); Candidate tmpBst = CandidateTable.GetBestCandidate(false); NetManagerGlobal.TempParent = tmpBst.GetMacID(); byte[] msg = new byte[NetManagerGlobal.HeartbeatMessageSize]; if (pipe.GetMsgWithMsgID(ref msg, index) == DeviceStatus.Success) { NetManagerGlobal.SendToTempParent(pipe, msg, msg.Length); tmpBst.UpdateNumTriesInCurrentWindow(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for TempParent " + transmitDestination + "; new value = " + tmpBst.GetNumTriesInCurrentWindow()); #endif _retriedPackets.Add(index); } } else // Retried once; drop packet { _retriedPackets.Remove(index); } break; default: break; } }
private static void DistResetStreamReceive(IMAC macBase, DateTime time, Packet packet) { #if DBG_VERBOSE DebuggingSupport.PrintMessageReceived(macBase, "Distributed Reset"); #endif if (packet == null) { return; } #if !DBG_LOGIC Debug.Print("\tRSSI: " + packet.RSSI + ", from " + packet.Src); #endif var rcvPayloadBytes = packet.Payload; //var payload = new string(Encoding.UTF8.GetChars(rcvPayloadBytes)); #if DBG_VERBOSE SystemGlobal.PrintNumericVals("\tDistributed reset Rcv: ", rcvPayloadBytes); #endif try { ushort[] neighbors = MACBase.NeighborListArray(); var neighborStatus = _distResetPipe.NeighborStatus(packet.Src); if (neighborStatus == null) { #if DBG_VERBOSE Debug.Print("\t\t!!!!!!!!!!!!!!!!! Node " + packet.Src + " is not a Neighbor (MACBase.NeighborStatus returned null)"); #elif DBG_SIMPLE Debug.Print("Sender not a neighbor."); #endif // If node in children table, drop it if (Array.IndexOf(_children._childrenList, packet.Src) < -1) { _children.DropChild(packet.Src); } return; } //Debug.Print("\t\tFwd avg RSSI: " + neighborStatus.ReceiveLink.AverageRSSI + ", Rev avg RSSI: " + neighborStatus.SendLink.AverageRSSI); switch ((MessageIds)rcvPayloadBytes[0]) { case MessageIds.AddParent: #if !DBG_LOGIC Debug.Print("\t>>> AddParent"); #endif if (_children.AddChild(packet.Src)) { #if DBG_VERBOSE Debug.Print("+++ Added new child: " + packet.Src + " +++"); #elif DBG_SIMPLE Debug.Print("Added new child: " + packet.Src); #endif } else { #if DBG_VERBOSE Debug.Print("@@@ Child already exists: " + packet.Src + " @@@"); #endif } return; case MessageIds.DropParent: #if !DBG_LOGIC Debug.Print("\t>>> DropParent"); #endif if (_children.DropChild(packet.Src)) { #if DBG_VERBOSE Debug.Print("--- Dropped child: " + packet.Src + " ---"); #elif DBG_SIMPLE Debug.Print("Dropped child: " + packet.Src); #endif } else { #if DBG_VERBOSE Debug.Print("@@@ Child does not exist: " + packet.Src + " @@@"); #endif } return; case MessageIds.Reset: #if !DBG_LOGIC Debug.Print("\t>>> ResetWave"); #endif // Decode round number ushort round_num; ParseMessages.ParseResetMessage(rcvPayloadBytes, out round_num); // Is this a legit reset wave? if (RoutingGlobal._color == Color.Red || packet.Src != RoutingGlobal.Parent || round_num != _resetMsgNum) { #if DBG_VERBOSE Debug.Print("!!! ILLEGAL RESET WAVE# " + round_num + ": Received from: " + packet.Src + " !!!"); #elif DBG_SIMPLE Debug.Print("Illegal reset wave " + round_num + " from " + packet.Src); #endif return; } // Refresh children table _children.CleanseChildrenTable(); if (_children.IsEmpty()) // Start completion wave if leaf node { #if DBG_VERBOSE Debug.Print("*** LEAF NODE REACHED: Initiating completion wave# " + round_num + " ***"); #elif DBG_SIMPLE Debug.Print("At leaf; initiating completion wave " + round_num); #endif Send_CompletionWave(round_num); // Create status query to existing candidates var msgBytes = new byte[3]; var size = ComposeMessages.CreateStatusQueryMessage(msgBytes, (ushort)_statusMsgNum); // Multicast query to candidates if (MulticastToCandidates(msgBytes, size)) // If there are candidates { // Wait for response _statusResponseTimer.Change(10000, Timeout.Infinite); // 10 second timer // Reset candidate table CandidateTable.Initialize((byte)neighbors.Length); } else //Empty candidate table; set parent immediately { // Set best node in candidate table as parent RoutingGlobal.SetParent(false); // Reset params RoutingGlobal._color = Color.Green; // Send "Add Parent" message to new parent DistributedReset.Send_AddParent(); _statusMsgNum++; } _resetMsgNum++; } else { // Forward reset wave to own children Send_ResetWave(rcvPayloadBytes); } return; case MessageIds.Completion: #if !DBG_LOGIC Debug.Print("\t>>> CompletionWave"); #endif // Decode round number ushort round; ParseMessages.ParseCompletionMessage(rcvPayloadBytes, out round); // Is this a legit completion wave? int pos = Array.IndexOf(_children._childrenList, packet.Src); if (RoutingGlobal._color != Color.Red || pos == -1 || round != _resetMsgNum) { #if DBG_VERBOSE Debug.Print("!!! ILLEGAL COMPLETION WAVE# " + round + ": Received from: " + packet.Src + " !!!"); #elif DBG_SIMPLE Debug.Print("Illegal completion wave " + round + " from " + packet.Src); #endif return; } _completionMsgs[pos] = true; // Forward completion wave if received from all children for (int i = 0; i < _completionMsgs.Length; i++) { if (!_completionMsgs[i]) // If not received from any child, return { return; } } // Else, forward completion wave to parent #if DBG_VERBOSE Debug.Print("*** RECEIVED COMPLETION MESSAGES FROM ALL CHILDREN: initiating completion wave# " + round + " ***"); #elif DBG_SIMPLE Debug.Print("All children responded; initiating completion wave " + round); #endif Send_CompletionWave(round); // Purge children table _children = new ChildrenList(); _completionMsgs = null; _distResetTimer.Change(Timeout.Infinite, Timeout.Infinite); // Create status query to existing candidates var msgBytes1 = new byte[3]; var size1 = ComposeMessages.CreateStatusQueryMessage(msgBytes1, (ushort)_statusMsgNum); // Multicast query to candidates if (MulticastToCandidates(msgBytes1, size1)) // If there are candidates { // Wait for response _statusResponseTimer.Change(10000, Timeout.Infinite); // 10 second timer // Reset candidate table CandidateTable.Initialize((byte)neighbors.Length); } else //Empty candidate table; set parent immediately { // Set best node in candidate table as parent RoutingGlobal.SetParent(false); // Reset params RoutingGlobal._color = Color.Green; // Send "Add Parent" message to new parent DistributedReset.Send_AddParent(); _statusMsgNum++; } _resetMsgNum++; return; case MessageIds.StatusQuery: #if !DBG_LOGIC Debug.Print("\t>>> StatusQuery"); #endif //If in a reset wave or no valid path, don't bother responding if (RoutingGlobal._color == Color.Red || RoutingGlobal.BestEtx >= RoutingGlobal.Infinity) { #if DBG_VERBOSE Debug.Print("!!! Not responding. Color: " + RoutingGlobal._color + ", BestEtx: " + RoutingGlobal.BestEtx + " !!!"); #elif DBG_SIMPLE Debug.Print("Not responding. Color: " + RoutingGlobal._color + ", BestEtx: " + RoutingGlobal.BestEtx); #endif return; } // Decode round number ushort status_msgnum; ParseMessages.ParseStatusQueryMessage(rcvPayloadBytes, out status_msgnum); // Send status response var msgBytes2 = new byte[5]; var size2 = ComposeMessages.CreateStatusResponseMessage(msgBytes2, status_msgnum); NetOpStatus status = _distResetPipe.Send(RoutingGlobal.Parent, msgBytes2, 0, (ushort)size2); return; case MessageIds.StatusResponse: #if !DBG_LOGIC Debug.Print("\t>>> StatusResponse"); #endif ushort status_respnum; Color col; byte etx; byte pathEWRNP_B2N; // Decode message ParseMessages.ParseStatusResponseMessage(rcvPayloadBytes, out col, out etx, out status_respnum, out pathEWRNP_B2N); // Is this a valid response? if (status_respnum != _statusMsgNum) { #if DBG_VERBOSE Debug.Print("!!! ILLEGAL STATUS RESPONSE# " + status_respnum + ": Received from: " + packet.Src + " !!!"); #elif DBG_SIMPLE Debug.Print("Illegal status response " + status_respnum + " from " + packet.Src); #endif return; } byte tempEtx = (byte)(etx + 1); // Add candidate if its offered etx exceeds _minEtx if (tempEtx >= RoutingGlobal._minEtx) { CandidateTable.AddCandidate(packet.Src, 0, tempEtx, pathEWRNP_B2N, RoutingGlobal.MaxEtx); // TODO: Add RSSI later #if DBG_VERBOSE Debug.Print("+++ Added new candidate: " + packet.Src + "; path length: " + tempEtx + " +++"); #elif DBG_SIMPLE Debug.Print("New candidate " + packet.Src + ":[" + tempEtx + "]"); #endif } else { #if DBG_VERBOSE Debug.Print("--- Not a candidate: " + packet.Src + "; path length: " + tempEtx + " ---"); #elif DBG_SIMPLE Debug.Print("Not a candidate " + packet.Src + ":[" + tempEtx + "]"); #endif } return; default: #if !DBG_LOGIC Debug.Print("\tUnknown message received <" + rcvPayloadBytes[0] + ">"); #endif break; } } catch (Exception e) { Debug.Print(e.StackTrace); } }
/// <summary> /// Construtor with custom hash function. /// </summary> /// <param name="digest">Hash function.</param> public PBKDF2(IHash digest, int iteration = 1000) { this._HashFunction = digest; this._MACFunction = new HMAC(this._HashFunction); this._Iteration = iteration; }
/// <summary> /// Default constructor. /// with HMAC-SHA1. /// </summary> public PBKDF2() { this._HashFunction = new Blake2b(512); this._MACFunction = new HMAC(this._HashFunction); this._Iteration = 1000; }
/// <summary> /// Print the neighbor list from MACBase instance /// </summary> /// <param name="macBase"></param> public static void PrintNeighborList(IMAC macBase) { macBase.NeighborList(Neighbors); PrintNumericVals("Neighbor List [for " + macBase.MACRadioObj.RadioAddress + "] ", Neighbors); }
/// <summary> /// Try get algorithm from mechanism. /// <para/>Used (block size / 2) as mac size by default. /// </summary> /// <param name="mechanism">Algorithm mechanism.</param> /// <param name="algorithm">Algorithm.</param> /// <returns></returns> public static bool TryGetAlgorithm(string mechanism, out IMAC algorithm) { return(TryGetAlgorithm(mechanism, -1, out algorithm)); }
/// <summary> /// Handle an App message /// </summary> /// <param name="macBase"></param> /// <param name="dateTime"></param> /// <param name="packet"></param> public static void AppPipeReceive(IMAC macBase, DateTime dateTime, Packet packet) { #if DBG_VERBOSE DebuggingSupport.PrintMessageReceived(macBase, "App"); #elif DBG_SIMPLE Debug.Print(""); Debug.Print("AppPipeReceive "); #endif try { #if !DBG_LOGIC Debug.Print("\tFrom " + packet.Src); #endif DebuggingSupport.PrintMessageReceived(macBase, "App"); //Debug.Print("\ton " + packet.PayloadType); //var rcvPayloadBytes = packet.Payload; //var rcvPayloadBytes = SystemGlobal.GetTrimmedPayload(packet); byte[] rcvPayloadBytes = packet.Payload; #if DBG_VERBOSE SystemGlobal.PrintNumericVals("App Rcv: ", rcvPayloadBytes); #elif DBG_SIMPLE Debug.Print(""); #endif switch ((AppGlobal.MessageIds)rcvPayloadBytes[0]) { case AppGlobal.MessageIds.Detect: { AppGlobal.ClassificationType classificationType; ushort originator; byte TTL; ushort detectionNumber; AppGlobal.MoteMessages.Parse.Detection(rcvPayloadBytes, out classificationType, out detectionNumber, out originator, out TTL); #if DBG_SIMPLE Debug.Print("\tDetect. From neighbor " + packet.Src + " # " + detectionNumber + ". Classification " + (char)classificationType + " created by " + originator + " with TTL " + TTL); #endif #if RELAY_NODE || CLIENT_NODE // Check if originated by self or if TTL-1 = 0 if (originator == AppGlobal.AppPipe.MACRadioObj.RadioAddress || --TTL == 0) { return; } #region Uncomment when scheduler disabled // If in a reset, do not forward TODO: Change this to "spray" if (RoutingGlobal._color == Color.Red) { #if DBG_VERBOSE Debug.Print("\tIn a Reset wave... not forwarded"); #endif return; } #endregion #region Uncomment when scheduler disabled /* TODO: Uncomment lines 368-394 when not using scheduler*/ // Not originated by self. // If parent is available, pass it on if (RoutingGlobal.IsParent) { byte[] routedMsg = new byte[rcvPayloadBytes.Length]; var size = AppGlobal.MoteMessages.Compose.Detection(routedMsg, originator, classificationType, detectionNumber, TTL); Debug.Print("routed message len: " + routedMsg.Length); Debug.Print("routedMsg: " + routedMsg.ToString()); var status = RoutingGlobal.SendToParent(AppGlobal.AppPipe, routedMsg, size); Debug.Print("status " + status); if (status != 999) { RoutingGlobal.UpdateNumTriesInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for Parent " + RoutingGlobal.Parent + "; new value = " + RoutingGlobal.GetNumTriesInCurrentWindow_Parent()); #endif } else //Retry once { #if !DBG_LOGIC Debug.Print("Retrying packet"); #endif if (status != 999) { RoutingGlobal.UpdateNumTriesInCurrentWindow_Parent(1); } } } #endregion #elif BASE_STATION var msg = AppGlobal.PCMessages.Compose.Detection(originator, classificationType, detectionNumber); try { _serialComm.Write(msg); #if DBG_VERBOSE Debug.Print("\n************ Detection sent to PC " + msg.Substring(1, msg.Length - 2)); #endif } catch (Exception ex) { Debug.Print("SerialComm exception for Detection message [" + msg + "]\n" + ex); } #endif break; } case AppGlobal.MessageIds.Send: { AppGlobal.ClassificationType classificationType; ushort originator; byte TTL; ushort sndNumber; ushort payloadLength; _lcd.Write("PSnd"); AppGlobal.MoteMessages.Parse.SendPacket(rcvPayloadBytes, out classificationType, out sndNumber, out originator, out TTL, out payloadLength); int rcvHeader = AppGlobal.SendMessageSize; byte[] sendPayload = new byte[payloadLength]; AppGlobal.MoteMessages.getPayload.SendPacket(rcvPayloadBytes, rcvHeader, sendPayload, (int)payloadLength); #if DBG_VERBOSE Debug.Print("Received Packet #" + sndNumber + " from neighbor " + packet.Src); Debug.Print(" Classification: " + (char)classificationType); Debug.Print(" Originator: " + originator); Debug.Print(" payload Length: " + payloadLength + "\n"); //Debug.Print("Received Packet # " + sndNumber + "From neighbor " + packet.Src + " with Classification " + (char)classificationType + ", created by " + originator + " with payload " + payloadString); #endif #if CLIENT_NODE Debug.Print("\tClient Recieved a send message..."); //_serialComm.Write(rcvPayloadBytes); #elif RELAY_NODE // Check if originated by self or if TTL-1 = 0 if (originator == AppGlobal.AppPipe.MACRadioObj.RadioAddress || --TTL == 0) { return; } #region Uncomment when scheduler disabled // If in a reset, do not forward TODO: Change this to "spray" if (RoutingGlobal._color == Color.Red) { #if DBG_VERBOSE Debug.Print("\tIn a Reset wave... not forwarded"); #endif return; } #endregion #region Uncomment when scheduler disabled /* TODO: Uncomment lines 368-394 when not using scheduler*/ // Not originated by self. // If parent is available, pass it on int payloadSize = sizeof(byte) * payloadLength; // remove ushort in length because popping first in path int rcvSize = rcvHeader + payloadSize; byte[] routedMsg = new byte[rcvSize]; if (RoutingGlobal.IsParent) { var headerSize = AppGlobal.MoteMessages.Compose.SendPacket(routedMsg, originator, classificationType, sndNumber, TTL, payloadLength); AppGlobal.MoteMessages.AddPayload.RecievePacket(routedMsg, headerSize, sendPayload, payloadLength); Debug.Print("Sending Packet # " + sndNumber + " to neighbor " + RoutingGlobal.Parent); Debug.Print(" Classification: " + (char)classificationType); Debug.Print(" Originator: " + originator); Debug.Print(" payload Length: " + payloadLength + "\n"); var status = RoutingGlobal.SendToParent(AppGlobal.AppPipe, routedMsg, rcvSize); //Neighbor(AppGlobal.AppPipe, next_neighbor, routedMsg, size); if (status != 999) { Debug.Print("Send Successful"); RoutingGlobal.UpdateNumTriesInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for Parent " + RoutingGlobal.Parent + "; new value = " + RoutingGlobal.GetNumTriesInCurrentWindow_Parent()); #endif } else //Retry once { #if !DBG_LOGIC Debug.Print("Retrying packet"); #endif status = RoutingGlobal.SendToParent(AppGlobal.AppPipe, routedMsg, rcvSize); if (status != 999) { Debug.Print("Send Successful"); //tmpBest.UpdateNumTriesInCurrentWindow(1); #if !DBG_LOGIC //Debug.Print("Updated numTriesInCurrentWindow for TempParent " + AppGlobal.TempParent + "; new value = " + tmpBest.GetNumTriesInCurrentWindow()); #endif } } } #endregion #elif BASE_STATION _packetNumber = sndNumber; _TTL = TTL; _payloadLength = payloadLength; _destination = originator; //Debug.Print("Base serial output: " + rcvString); _serialComm.Write(sendPayload); /* * var rcvString = new string(System.Text.Encoding.UTF8.GetChars(rcvPayloadBytes)); * Debug.Print("Base serial output: " + rcvString); * _serialComm.Write(rcvString); * * //wait for reply * int rcvSize = AppGlobal.MoteMessages.Length.SendPacket(pathLength, payloadLength); * classificationType = AppGlobal.ClassificationType.Recieve; * byte[] rcvPayload; * if (payloadLength == 1) * { * rcvPayload = BitConverter.GetBytes(GetBaseReply(sendPayload)); * } * else * { * rcvPayload = BitConverter.GetBytes('c'); * } * int rcvPayloadLength = rcvPayload.Length; * * ushort next_neighbor = path[pathLength - 1]; * * int headerSize = AppGlobal.MoteMessages.Compose.RecievePacket(rcvPayloadBytes, originator, classificationType, sndNumber, TTL, pathLength, path, payloadLength); * AppGlobal.MoteMessages.AddPayload.RecievePacket(rcvPayloadBytes, headerSize, rcvPayload, rcvPayloadLength); * #if DBG_VERBOSE * Debug.Print("Sending Packet #" + sndNumber + " to neighbor " + next_neighbor); * Debug.Print(" Classification: " + (char)classificationType); * Debug.Print(" Originator: " + originator); * Debug.Print(" path Length: " + pathLength); * Debug.Print(" payload Length: " + rcvPayloadLength + "\n"); #endif * try * { #if DBG_VERBOSE * Debug.Print("Send Successful"); #endif * var status = RoutingGlobal.SendToNeighbor(AppGlobal.AppPipe, next_neighbor, rcvPayloadBytes, rcvSize); * #if DBG_VERBOSE * Debug.Print("\n************ Detection sent to PC " + msg.Substring(1,msg.Length-2)); #endif * } * catch (Exception ex) * { * Debug.Print("SerialComm exception for Detection message [" + rcvSize + "]\n" + ex); * } */ #endif break; } case AppGlobal.MessageIds.Recieve: { AppGlobal.ClassificationType classificationType; ushort originator; ushort destination; byte TTL; ushort rcvNumber; ushort payloadLength; _lcd.Write("PRcv"); AppGlobal.MoteMessages.Parse.RecievePacket(rcvPayloadBytes, out classificationType, out rcvNumber, out originator, out destination, out TTL, out payloadLength); #if DBG_VERBOSE Debug.Print("Received Packet #" + rcvNumber + " from neighbor " + packet.Src); Debug.Print(" Classification: " + (char)classificationType); Debug.Print(" Originator: " + originator); Debug.Print(" payload Length: " + payloadLength + "\n"); #endif //Debug.Print("\tRecieve. From neighbor " + packet.Src + " # " + rcvNumber + ". Classification " + (char)classificationType + " created by " + originator + " with TTL " + TTL); #if CLIENT_NODE int rcvHeader = AppGlobal.RecieveMessageSize; byte[] rcvPayload = new byte[payloadLength]; AppGlobal.MoteMessages.getPayload.RecievePacket(rcvPayloadBytes, rcvHeader, rcvPayload, (int)payloadLength); //var rcvString = new string(System.Text.Encoding.UTF8.GetChars(rcvPayload)); //Debug.Print("Client serial output: " + rcvString); _serialComm.Write(rcvPayloadBytes); #elif RELAY_NODE // Check if originated by self or if TTL-1 = 0 if (originator == AppGlobal.AppPipe.MACRadioObj.RadioAddress || --TTL == 0) { return; } #region Uncomment when scheduler disabled // If in a reset, do not forward TODO: Change this to "spray" if (RoutingGlobal._color == Color.Red) { #if DBG_VERBOSE Debug.Print("\tIn a Reset wave... not forwarded"); #endif return; } #endregion #region Uncomment when scheduler disabled /* TODO: Uncomment lines 368-394 when not using scheduler*/ // Not originated by self. // If parent is available, pass it on int sndHeader = AppGlobal.RecieveMessageSize; byte[] sndPayload = new byte[payloadLength]; AppGlobal.MoteMessages.getPayload.SendPacket(rcvPayloadBytes, sndHeader, sndPayload, (int)payloadLength); int sendSize = sndHeader + payloadLength; var routedMsg = new byte[sendSize]; var headerSize = AppGlobal.MoteMessages.Compose.RecievePacket(routedMsg, originator, classificationType, rcvNumber, TTL, payloadLength); AppGlobal.MoteMessages.AddPayload.RecievePacket(routedMsg, headerSize, sndPayload, payloadLength); #if DBG_VERBOSE Debug.Print("Sending Packet # " + rcvNumber + " to child"); Debug.Print(" Classification: " + (char)classificationType); Debug.Print(" Originator: " + originator); Debug.Print(" payload Length: " + payloadLength + "\n"); #endif var status = RoutingGlobal.SendToChild(AppGlobal.AppPipe, destination, routedMsg, sendSize); if (status != 999) { Debug.Print("Send Successful"); RoutingGlobal.UpdateNumTriesInCurrentWindow_Parent(1); #if !DBG_LOGIC Debug.Print("Updated numTriesInCurrentWindow for Parent " + RoutingGlobal.Parent + "; new value = " + RoutingGlobal.GetNumTriesInCurrentWindow_Parent()); #endif } else //Retry once { #if !DBG_LOGIC Debug.Print("Retrying packet"); #endif status = RoutingGlobal.SendToChild(AppGlobal.AppPipe, destination, routedMsg, sendSize); if (status != 999) { Debug.Print("Send Successful"); //tmpBest.UpdateNumTriesInCurrentWindow(1); #if !DBG_LOGIC //Debug.Print("Updated numTriesInCurrentWindow for TempParent " + AppGlobal.TempParent + "; new value = " + tmpBest.GetNumTriesInCurrentWindow()); #endif } } #endregion #elif BASE_STATION #endif break; } default: Debug.Print("AppPipeReceive unknown rcvPayloadBytes[0] "); throw new ArgumentOutOfRangeException(); } #region unused ////var rcvPayloadChar = Encoding.UTF8.GetChars(rcvPayloadBytes); ////var payload = new string(rcvPayloadChar); //if (payload.Substring(0, 5).Equals("Human")) //Data packets--human //{ // Debug.Print("\n\tReceived decision: " + payload.Substring(0, 5) + "; source: " + payload.Substring(5) + "; from Node: " + packet.Src); // _lcd.Write("" + (++_numData)); //} //if (RoutingGlobal.Parent == SystemGlobal.NoParent) //{ // Debug.Print("\tNo parent specified "); // return; //} ////Debug.Print("\t\t*** Parent: "+ Parent+", SelfAddress: "+SelfAddress); //if (RoutingGlobal.Parent == _routing.SelfAddress) //{ // Debug.Print("\tAt base"); // return; //} //var toSendByte = Encoding.UTF8.GetBytes(payload); //var status = AppPipe.Send(RoutingGlobal.Parent, toSendByte, 0, (ushort)toSendByte.Length); //if (status != NetOpStatus.S_Success) //{ // Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Send status: " + status); //} //SystemGlobal.PrintNumericVals("App Snd: ", toSendByte); //Debug.Print("Forwarded to parent node: " + RoutingGlobal.Parent); #endregion } catch (Exception e) { Debug.Print(e.ToString()); } }
/// <summary> /// Try get algorithm from mechanism. /// <para/>Legal mac size is between 8 and block size (8 bits increments). /// <para/>Legal mac size must be at least 24 bits (FIPS Publication 81) or 16 bits if being used as a data authenticator (FIPS Publication 113). /// <para/>Used (block size / 2) as mac size by default. /// </summary> /// <param name="mechanism">Algorithm mechanism.</param> /// <param name="macSize">MAC size bits.</param> /// <param name="algorithm">Algorithm.</param> /// <returns></returns> public static bool TryGetAlgorithm(string mechanism, int macSize, out IMAC algorithm) { mechanism = mechanism.Replace('_', '-').ToUpperInvariant(); if (mechanism.EndsWith("MAC")) { if (mechanism.EndsWith("/MAC") || mechanism.EndsWith("-MAC")) { mechanism = mechanism.Substring(0, mechanism.Length - 4); } else { mechanism = mechanism.Substring(0, mechanism.Length - 3); } } mechanism = mechanism.Replace('/', '-'); switch (mechanism) { case "AES": return(TryGetNanoAlgorithm(AES_MAC, macSize, out algorithm)); case "BLOWFISH": return(TryGetNanoAlgorithm(Blowfish_MAC, macSize, out algorithm)); case "CAMELLIA": return(TryGetNanoAlgorithm(Camellia_MAC, macSize, out algorithm)); case "CAST5": return(TryGetNanoAlgorithm(CAST5_MAC, macSize, out algorithm)); case "CAST6": return(TryGetNanoAlgorithm(CAST6_MAC, macSize, out algorithm)); case "DES": return(TryGetNanoAlgorithm(DES_MAC, macSize, out algorithm)); case "DESEDE": case "DESEDE3": case "TDEA": case "TRIPLEDES": case "3DES": return(TryGetNanoAlgorithm(DESede_MAC, macSize, out algorithm)); case "DSTU7624-128": return(TryGetNanoAlgorithm(DSTU7624_128_MAC, macSize, out algorithm)); case "DSTU7624-256": return(TryGetNanoAlgorithm(DSTU7624_256_MAC, macSize, out algorithm)); case "DSTU7624-512": return(TryGetNanoAlgorithm(DSTU7624_512_MAC, macSize, out algorithm)); case "GOST28147": return(TryGetNanoAlgorithm(GOST28147_MAC, macSize, out algorithm)); case "IDEA": return(TryGetNanoAlgorithm(IDEA_MAC, macSize, out algorithm)); case "NOEKEON": return(TryGetNanoAlgorithm(Noekeon_MAC, macSize, out algorithm)); case "RC2": return(TryGetNanoAlgorithm(RC2_MAC, macSize, out algorithm)); case "RC5": case "RC5-32": return(TryGetNanoAlgorithm(RC5_MAC, macSize, out algorithm)); case "RC5-64": return(TryGetNanoAlgorithm(RC5_64_MAC, macSize, out algorithm)); case "RC6": return(TryGetNanoAlgorithm(RC6_MAC, macSize, out algorithm)); case "RIJNDAEL-128": case "RIJNDAEL128": return(TryGetNanoAlgorithm(Rijndael_128_MAC, macSize, out algorithm)); case "RIJNDAEL-160": case "RIJNDAEL160": return(TryGetNanoAlgorithm(Rijndael_160_MAC, macSize, out algorithm)); case "RIJNDAEL-192": case "RIJNDAEL192": return(TryGetNanoAlgorithm(Rijndael_192_MAC, macSize, out algorithm)); case "RIJNDAEL-224": case "RIJNDAEL224": return(TryGetNanoAlgorithm(Rijndael_224_MAC, macSize, out algorithm)); case "RIJNDAEL-256": case "RIJNDAEL256": return(TryGetNanoAlgorithm(Rijndael_256_MAC, macSize, out algorithm)); case "SEED": return(TryGetNanoAlgorithm(SEED_MAC, macSize, out algorithm)); case "SERPENT": return(TryGetNanoAlgorithm(Serpent_MAC, macSize, out algorithm)); case "SKIPJACK": return(TryGetNanoAlgorithm(SKIPJACK_MAC, macSize, out algorithm)); case "SM4": return(TryGetNanoAlgorithm(SM4_MAC, macSize, out algorithm)); case "TEA": return(TryGetNanoAlgorithm(TEA_MAC, macSize, out algorithm)); case "THREEFISH-256": case "THREEFISH256": return(TryGetNanoAlgorithm(Threefish_256_MAC, macSize, out algorithm)); case "THREEFISH-512": case "THREEFISH512": return(TryGetNanoAlgorithm(Threefish_512_MAC, macSize, out algorithm)); case "THREEFISH-1024": case "THREEFISH1024": return(TryGetNanoAlgorithm(Threefish_1024_MAC, macSize, out algorithm)); case "TNEPRES": return(TryGetNanoAlgorithm(Tnepres_MAC, macSize, out algorithm)); case "TWOFISH": return(TryGetNanoAlgorithm(Twofish_MAC, macSize, out algorithm)); case "XTEA": return(TryGetNanoAlgorithm(XTEA_MAC, macSize, out algorithm)); default: algorithm = null; return(false); } }