DualShockPadMeta GetPadDetailForIdx(int padIdx) { var meta = new DualShockPadMeta(); meta.PadId = (byte)padIdx; meta.Model = DsModel.DS4; var d = DS4Controllers[padIdx]; if (d == null) { meta.PadMacAddress = null; meta.PadState = DsState.Disconnected; meta.ConnectionType = DsConnection.None; meta.Model = DsModel.None; meta.BatteryStatus = 0; meta.IsActive = false; return(meta); } bool isValidSerial = false; if (d.isValidSerial()) { string stringMac = d.getMacAddress(); if (stringMac != null) { stringMac = stringMac.Replace(":", "").Trim(); if (stringMac.Length > 0) { meta.PadMacAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(stringMac); isValidSerial = true; if (d.isSynced() || d.IsAlive()) { meta.PadState = DsState.Connected; } else { meta.PadState = DsState.Reserved; } } } } if (!isValidSerial) { meta.PadMacAddress = null; meta.PadState = DsState.Disconnected; } meta.ConnectionType = (d.getConnectionType() == ConnectionType.USB) ? DsConnection.Usb : DsConnection.Bluetooth; meta.IsActive = !d.isDS4Idle(); if (d.isCharging() && d.getBattery() >= 100) { meta.BatteryStatus = DsBattery.Charged; } else { if (d.getBattery() >= 95) { meta.BatteryStatus = DsBattery.Full; } else if (d.getBattery() >= 70) { meta.BatteryStatus = DsBattery.High; } else if (d.getBattery() >= 50) { meta.BatteryStatus = DsBattery.Medium; } else if (d.getBattery() >= 20) { meta.BatteryStatus = DsBattery.Low; } else if (d.getBattery() >= 5) { meta.BatteryStatus = DsBattery.Dying; } else { meta.BatteryStatus = DsBattery.None; } } return(meta); }
private void ProcessIncoming(byte[] localMsg, IPEndPoint clientEP) { try { int currIdx = 0; if (localMsg[0] != 'D' || localMsg[1] != 'S' || localMsg[2] != 'U' || localMsg[3] != 'C') { return; } else { currIdx += 4; } uint protocolVer = BitConverter.ToUInt16(localMsg, currIdx); currIdx += 2; if (protocolVer > MaxProtocolVersion) { return; } uint packetSize = BitConverter.ToUInt16(localMsg, currIdx); currIdx += 2; if (packetSize < 0) { return; } packetSize += 16; //size of header if (packetSize > localMsg.Length) { return; } else if (packetSize < localMsg.Length) { byte[] newMsg = new byte[packetSize]; Array.Copy(localMsg, newMsg, packetSize); localMsg = newMsg; } uint crcValue = BitConverter.ToUInt32(localMsg, currIdx); //zero out the crc32 in the packet once we got it since that's whats needed for calculation localMsg[currIdx++] = 0; localMsg[currIdx++] = 0; localMsg[currIdx++] = 0; localMsg[currIdx++] = 0; uint crcCalc = Crc32Algorithm.Compute(localMsg); if (crcValue != crcCalc) { return; } uint clientId = BitConverter.ToUInt32(localMsg, currIdx); currIdx += 4; uint messageType = BitConverter.ToUInt32(localMsg, currIdx); currIdx += 4; if (messageType == (uint)MessageType.DSUC_VersionReq) { byte[] outputData = new byte[8]; int outIdx = 0; Array.Copy(BitConverter.GetBytes((uint)MessageType.DSUS_VersionRsp), 0, outputData, outIdx, 4); outIdx += 4; Array.Copy(BitConverter.GetBytes((ushort)MaxProtocolVersion), 0, outputData, outIdx, 2); outIdx += 2; outputData[outIdx++] = 0; outputData[outIdx++] = 0; SendPacket(clientEP, outputData, 1001); } else if (messageType == (uint)MessageType.DSUC_ListPorts) { int numPadRequests = BitConverter.ToInt32(localMsg, currIdx); currIdx += 4; if (numPadRequests < 0 || numPadRequests > NUMBER_SLOTS) { return; } int requestsIdx = currIdx; for (int i = 0; i < numPadRequests; i++) { byte currRequest = localMsg[requestsIdx + i]; if (currRequest >= NUMBER_SLOTS) { return; } } byte[] outputData = new byte[16]; for (byte i = 0; i < numPadRequests; i++) { byte currRequest = localMsg[requestsIdx + i]; DualShockPadMeta padData = new DualShockPadMeta(); portInfoGet(currRequest, ref padData); int outIdx = 0; Array.Copy(BitConverter.GetBytes((uint)MessageType.DSUS_PortInfo), 0, outputData, outIdx, 4); outIdx += 4; outputData[outIdx++] = (byte)padData.PadId; outputData[outIdx++] = (byte)padData.PadState; outputData[outIdx++] = (byte)padData.Model; outputData[outIdx++] = (byte)padData.ConnectionType; byte[] addressBytes = null; if (padData.PadMacAddress != null) { addressBytes = padData.PadMacAddress.GetAddressBytes(); } if (addressBytes != null && addressBytes.Length == 6) { outputData[outIdx++] = addressBytes[0]; outputData[outIdx++] = addressBytes[1]; outputData[outIdx++] = addressBytes[2]; outputData[outIdx++] = addressBytes[3]; outputData[outIdx++] = addressBytes[4]; outputData[outIdx++] = addressBytes[5]; } else { outputData[outIdx++] = 0; outputData[outIdx++] = 0; outputData[outIdx++] = 0; outputData[outIdx++] = 0; outputData[outIdx++] = 0; outputData[outIdx++] = 0; } outputData[outIdx++] = (byte)padData.BatteryStatus; outputData[outIdx++] = 0; SendPacket(clientEP, outputData, 1001); } } else if (messageType == (uint)MessageType.DSUC_PadDataReq) { byte regFlags = localMsg[currIdx++]; byte idToReg = localMsg[currIdx++]; PhysicalAddress macToReg = null; { byte[] macBytes = new byte[6]; Array.Copy(localMsg, currIdx, macBytes, 0, macBytes.Length); currIdx += macBytes.Length; macToReg = new PhysicalAddress(macBytes); } lock (clients) { if (clients.ContainsKey(clientEP)) { clients[clientEP].RequestPadInfo(regFlags, idToReg, macToReg); } else { var clientTimes = new ClientRequestTimes(); clientTimes.RequestPadInfo(regFlags, idToReg, macToReg); clients[clientEP] = clientTimes; } } } } catch (Exception /*e*/) { } }
public void NewReportIncoming(ref DualShockPadMeta padMeta, DS4State hidReport, byte[] outputData) { if (!running) { return; } var clientsList = new List <IPEndPoint>(); var now = DateTime.UtcNow; lock (clients) { var clientsToDelete = new List <IPEndPoint>(); foreach (var cl in clients) { const double TimeoutLimit = 5; if ((now - cl.Value.AllPadsTime).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if ((padMeta.PadId < cl.Value.PadIdsTime.Length) && (now - cl.Value.PadIdsTime[(byte)padMeta.PadId]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if (cl.Value.PadMacsTime.ContainsKey(padMeta.PadMacAddress) && (now - cl.Value.PadMacsTime[padMeta.PadMacAddress]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else //check if this client is totally dead, and remove it if so { bool clientOk = false; for (int i = 0; i < cl.Value.PadIdsTime.Length; i++) { var dur = (now - cl.Value.PadIdsTime[i]).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { foreach (var dict in cl.Value.PadMacsTime) { var dur = (now - dict.Value).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { clientsToDelete.Add(cl.Key); } } } } foreach (var delCl in clientsToDelete) { clients.Remove(delCl); } clientsToDelete.Clear(); clientsToDelete = null; } if (clientsList.Count <= 0) { return; } unchecked { //byte[] outputData = new byte[100]; int outIdx = BeginPacket(outputData, 1001); Array.Copy(BitConverter.GetBytes((uint)MessageType.DSUS_PadDataRsp), 0, outputData, outIdx, 4); outIdx += 4; outputData[outIdx++] = (byte)padMeta.PadId; outputData[outIdx++] = (byte)padMeta.PadState; outputData[outIdx++] = (byte)padMeta.Model; outputData[outIdx++] = (byte)padMeta.ConnectionType; { byte[] padMac = padMeta.PadMacAddress.GetAddressBytes(); outputData[outIdx++] = padMac[0]; outputData[outIdx++] = padMac[1]; outputData[outIdx++] = padMac[2]; outputData[outIdx++] = padMac[3]; outputData[outIdx++] = padMac[4]; outputData[outIdx++] = padMac[5]; } outputData[outIdx++] = (byte)padMeta.BatteryStatus; outputData[outIdx++] = padMeta.IsActive ? (byte)1 : (byte)0; Array.Copy(BitConverter.GetBytes((uint)hidReport.PacketCounter), 0, outputData, outIdx, 4); outIdx += 4; if (!ReportToBuffer(hidReport, outputData, ref outIdx)) { return; } else { FinishPacket(outputData); } foreach (var cl in clientsList) { //try { udpSock.SendTo(outputData, cl); } int temp = 0; poolLock.EnterWriteLock(); temp = listInd; listInd = ++listInd % ARG_BUFFER_LEN; SocketAsyncEventArgs args = argsList[temp]; poolLock.ExitWriteLock(); _pool.Wait(); args.RemoteEndPoint = cl; Array.Copy(outputData, args.Buffer, outputData.Length); bool sentAsync = false; try { sentAsync = udpSock.SendToAsync(args); } catch (SocketException /*ex*/) { } finally { if (!sentAsync) { CompletedSynchronousSocketEvent(); } } } } clientsList.Clear(); clientsList = null; }
public void NewReportIncoming(DualShockPadMeta padMeta, DS4State hidReport) { if (!running) { return; } var clientsList = new List <IPEndPoint>(); var now = DateTime.UtcNow; lock (clients) { var clientsToDelete = new List <IPEndPoint>(); foreach (var cl in clients) { const double TimeoutLimit = 5; if ((now - cl.Value.AllPadsTime).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if ((padMeta.PadId < cl.Value.PadIdsTime.Length) && (now - cl.Value.PadIdsTime[(byte)padMeta.PadId]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else if (cl.Value.PadMacsTime.ContainsKey(padMeta.PadMacAddress) && (now - cl.Value.PadMacsTime[padMeta.PadMacAddress]).TotalSeconds < TimeoutLimit) { clientsList.Add(cl.Key); } else //check if this client is totally dead, and remove it if so { bool clientOk = false; for (int i = 0; i < cl.Value.PadIdsTime.Length; i++) { var dur = (now - cl.Value.PadIdsTime[i]).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { foreach (var dict in cl.Value.PadMacsTime) { var dur = (now - dict.Value).TotalSeconds; if (dur < TimeoutLimit) { clientOk = true; break; } } if (!clientOk) { clientsToDelete.Add(cl.Key); } } } } foreach (var delCl in clientsToDelete) { clients.Remove(delCl); } clientsToDelete.Clear(); clientsToDelete = null; } if (clientsList.Count <= 0) { return; } byte[] outputData = new byte[100]; int outIdx = BeginPacket(outputData, 1001); Array.Copy(BitConverter.GetBytes((uint)MessageType.DSUS_PadDataRsp), 0, outputData, outIdx, 4); outIdx += 4; outputData[outIdx++] = (byte)padMeta.PadId; outputData[outIdx++] = (byte)padMeta.PadState; outputData[outIdx++] = (byte)padMeta.Model; outputData[outIdx++] = (byte)padMeta.ConnectionType; { byte[] padMac = padMeta.PadMacAddress.GetAddressBytes(); outputData[outIdx++] = padMac[0]; outputData[outIdx++] = padMac[1]; outputData[outIdx++] = padMac[2]; outputData[outIdx++] = padMac[3]; outputData[outIdx++] = padMac[4]; outputData[outIdx++] = padMac[5]; } outputData[outIdx++] = (byte)padMeta.BatteryStatus; outputData[outIdx++] = padMeta.IsActive ? (byte)1 : (byte)0; Array.Copy(BitConverter.GetBytes((uint)hidReport.PacketCounter), 0, outputData, outIdx, 4); outIdx += 4; if (!ReportToBuffer(hidReport, outputData, ref outIdx)) { return; } else { FinishPacket(outputData); } foreach (var cl in clientsList) { try { udpSock.SendTo(outputData, cl); } catch (SocketException ex) { } } clientsList.Clear(); clientsList = null; }