private PeerQueryData ByteArrayToPeerData(byte[] bytes, int offset) { if (offset + 100 > bytes.Length) { return(null); } PeerQueryData data = new PeerQueryData { Number = BitConverter.ToUInt32(bytes, offset).ToString(), LongName = Encoding.ASCII.GetString(bytes, offset + 4, 40).Trim(new char[] { '\x00' }), SpecialAttribute = BitConverter.ToUInt16(bytes, offset + 44), PeerType = bytes[offset + 46], HostName = Encoding.ASCII.GetString(bytes, offset + 47, 40).Trim(new char[] { '\x00' }), IpAddress = $"{bytes[offset + 87]}.{bytes[offset + 88]}.{bytes[offset + 89]}.{bytes[offset + 90]}", PortNumber = BitConverter.ToUInt16(bytes, offset + 91), ExtensionNumber = bytes[offset + 93], Pin = BitConverter.ToUInt16(bytes, offset + 94) }; UInt32 timestamp = BitConverter.ToUInt32(bytes, offset + 96); DateTime dt = new DateTime(1900, 1, 1, 0, 0, 0, 0); data.LastChange = dt.AddSeconds(timestamp); return(data); }
/// <summary> /// Query for search string /// </summary> /// <param name="name"></param> /// <returns>search reply with list of peers</returns> private PeerSearchReply SendPeerSearch(string name) { Logging.Instance.Log(LogTypes.Debug, TAG, nameof(SendPeerSearch), $"name='{name}'"); PeerSearchReply reply = new PeerSearchReply(); if (client == null) { Logging.Instance.Error(TAG, nameof(SendPeerSearch), "no server connection"); reply.Error = "no server connection"; return(reply); } if (string.IsNullOrEmpty(name)) { reply.Error = "no search name"; return(reply); } byte[] sendData = new byte[43]; sendData[0] = 0x0A; // Peer_search sendData[1] = 0x29; // length sendData[2] = 0x01;; // version 1 byte[] txt = Encoding.ASCII.GetBytes(name); Buffer.BlockCopy(txt, 0, sendData, 3, txt.Length); try { stream.Write(sendData, 0, sendData.Length); } catch (Exception ex) { Message?.Invoke(LngText(LngKeys.Message_SubscribeServerError)); Logging.Instance.Error(TAG, nameof(SendPeerQuery), $"error sending data to subscribe server", ex); reply.Valid = false; reply.Error = "reply server error"; return(reply); } byte[] ack = new byte[] { 0x08, 0x00 }; List <PeerQueryData> list = new List <PeerQueryData>(); while (true) { byte[] recvData = new byte[102]; int recvLen = 0; try { recvLen = stream.Read(recvData, 0, recvData.Length); } catch (Exception ex) { Logging.Instance.Error(TAG, nameof(SendPeerQuery), $"error receiving data from subscribe server", ex); reply.Valid = false; reply.Error = "reply server error"; return(reply); } //Logging.Instance.Log(LogTypes.Debug, TAG, nameof(SendPeerSearch), $"recvLen={recvLen}"); if (recvLen == 0) { Logging.Instance.Log(LogTypes.Error, TAG, nameof(SendPeerSearch), $"recvLen=0"); reply.Error = $"no data received"; return(reply); } if (recvData[0] == 0x09) { // end of list break; } if (recvLen < 2 + 0x64) { Logging.Instance.Log(LogTypes.Warn, TAG, nameof(SendPeerSearch), $"received data to short ({recvLen} bytes)"); reply.Error = $"received data to short ({recvLen} bytes)"; continue; } if (recvData[1] != 0x64) { Logging.Instance.Log(LogTypes.Warn, TAG, nameof(SendPeerSearch), $"invalid length value ({recvData[1]})"); reply.Error = $"invalid length value ({recvData[1]})"; continue; } PeerQueryData data = ByteArrayToPeerData(recvData, 2); Logging.Instance.Log(LogTypes.Debug, TAG, nameof(SendPeerSearch), $"found {data}"); list.Add(data); // send ack try { stream.Write(ack, 0, ack.Length); } catch (Exception ex) { Logging.Instance.Error(TAG, nameof(SendPeerQuery), $"error sending data to subscribe server", ex); return(null); } } list.Sort(new PeerQueryDataSorter(PeerQueryDataSorter.Sort.Number)); reply.List = list.ToArray(); reply.Valid = true; reply.Error = "ok"; return(reply); }