// GetRegisterInfo(bytes<8, 4>) -> buffer<unknown<0x100>, 0x1a> public ResultCode GetRegisterInfo(ServiceCtx context) { ResultCode resultCode = CheckNfcIsEnabled(); if (resultCode != ResultCode.Success) { return(resultCode); } if (context.Request.RecvListBuff.Count == 0) { return(ResultCode.WrongArgument); } ulong outputPosition = context.Request.RecvListBuff[0].Position; context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(RegisterInfo))); MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(RegisterInfo))); uint deviceHandle = (uint)context.RequestData.ReadUInt64(); if (context.Device.System.NfpDevices.Count == 0) { return(ResultCode.DeviceNotFound); } for (int i = 0; i < context.Device.System.NfpDevices.Count; i++) { if (context.Device.System.NfpDevices[i].Handle == (PlayerIndex)deviceHandle) { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagRemoved) { resultCode = ResultCode.TagNotFound; } else { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagMounted) { RegisterInfo registerInfo = VirtualAmiibo.GetRegisterInfo( context.Device.System.TickSource, context.Device.System.NfpDevices[i].AmiiboId, context.Device.System.AccountManager.LastOpenedUser.Name); context.Memory.Write(outputPosition, registerInfo); resultCode = ResultCode.Success; } else { resultCode = ResultCode.WrongDeviceState; } } break; } } return(resultCode); }
// CreateApplicationArea(bytes<8, 4>, u32, buffer<unknown, 5>) public ResultCode CreateApplicationArea(ServiceCtx context) { ResultCode resultCode = CheckNfcIsEnabled(); if (resultCode != ResultCode.Success) { return(resultCode); } uint deviceHandle = (uint)context.RequestData.ReadUInt64(); if (context.Device.System.NfpDevices.Count == 0) { return(ResultCode.DeviceNotFound); } uint applicationAreaId = context.RequestData.ReadUInt32(); ulong inputPosition = context.Request.SendBuff[0].Position; ulong inputSize = context.Request.SendBuff[0].Size; byte[] applicationArea = new byte[inputSize]; context.Memory.Read(inputPosition, applicationArea); bool isCreated = false; for (int i = 0; i < context.Device.System.NfpDevices.Count; i++) { if (context.Device.System.NfpDevices[i].Handle == (PlayerIndex)deviceHandle) { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagRemoved) { resultCode = ResultCode.TagNotFound; } else { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagMounted) { isCreated = VirtualAmiibo.CreateApplicationArea(context.Device.System.NfpDevices[i].AmiiboId, applicationAreaId, applicationArea); resultCode = ResultCode.Success; } else { resultCode = ResultCode.WrongDeviceState; } } break; } } if (!isCreated) { resultCode = ResultCode.ApplicationAreaIsNull; } return(resultCode); }
// OpenApplicationArea(bytes<8, 4>, u32) public ResultCode OpenApplicationArea(ServiceCtx context) { ResultCode resultCode = CheckNfcIsEnabled(); if (resultCode != ResultCode.Success) { return(resultCode); } uint deviceHandle = (uint)context.RequestData.ReadUInt64(); if (context.Device.System.NfpDevices.Count == 0) { return(ResultCode.DeviceNotFound); } uint applicationAreaId = context.RequestData.ReadUInt32(); bool isOpened = false; for (int i = 0; i < context.Device.System.NfpDevices.Count; i++) { if (context.Device.System.NfpDevices[i].Handle == (PlayerIndex)deviceHandle) { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagRemoved) { resultCode = ResultCode.TagNotFound; } else { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagMounted) { isOpened = VirtualAmiibo.OpenApplicationArea(context.Device.System.NfpDevices[i].AmiiboId, applicationAreaId); resultCode = ResultCode.Success; } else { resultCode = ResultCode.WrongDeviceState; } } break; } } if (!isOpened) { resultCode = ResultCode.ApplicationAreaIsNull; } return(resultCode); }
// GetTagInfo(bytes<8, 4>) -> buffer<unknown<0x58>, 0x1a> public ResultCode GetTagInfo(ServiceCtx context) { ResultCode resultCode = CheckNfcIsEnabled(); if (resultCode != ResultCode.Success) { return(resultCode); } if (context.Request.RecvListBuff.Count == 0) { return(ResultCode.WrongArgument); } ulong outputPosition = context.Request.RecvListBuff[0].Position; context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(TagInfo))); MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(TagInfo))); uint deviceHandle = (uint)context.RequestData.ReadUInt64(); if (context.Device.System.NfpDevices.Count == 0) { return(ResultCode.DeviceNotFound); } for (int i = 0; i < context.Device.System.NfpDevices.Count; i++) { if (context.Device.System.NfpDevices[i].Handle == (PlayerIndex)deviceHandle) { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagRemoved) { resultCode = ResultCode.TagNotFound; } else { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagMounted || context.Device.System.NfpDevices[i].State == NfpDeviceState.TagFound) { byte[] Uuid = VirtualAmiibo.GenerateUuid(context.Device.System.NfpDevices[i].AmiiboId, context.Device.System.NfpDevices[i].UseRandomUuid); if (Uuid.Length > AmiiboConstants.UuidMaxLength) { throw new ArgumentOutOfRangeException(); } TagInfo tagInfo = new TagInfo { UuidLength = (byte)Uuid.Length, Reserved1 = new Array21 <byte>(), Protocol = uint.MaxValue, // All Protocol TagType = uint.MaxValue, // All Type Reserved2 = new Array6 <byte>() }; Uuid.CopyTo(tagInfo.Uuid.ToSpan()); context.Memory.Write(outputPosition, tagInfo); resultCode = ResultCode.Success; } else { resultCode = ResultCode.WrongDeviceState; } } break; } } return(resultCode); }
// GetApplicationArea(bytes<8, 4>) -> (u32, buffer<unknown, 6>) public ResultCode GetApplicationArea(ServiceCtx context) { ResultCode resultCode = CheckNfcIsEnabled(); if (resultCode != ResultCode.Success) { return(resultCode); } uint deviceHandle = (uint)context.RequestData.ReadUInt64(); if (context.Device.System.NfpDevices.Count == 0) { return(ResultCode.DeviceNotFound); } ulong outputPosition = context.Request.ReceiveBuff[0].Position; ulong outputSize = context.Request.ReceiveBuff[0].Size; MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize); uint size = 0; for (int i = 0; i < context.Device.System.NfpDevices.Count; i++) { if (context.Device.System.NfpDevices[i].Handle == (PlayerIndex)deviceHandle) { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagRemoved) { resultCode = ResultCode.TagNotFound; } else { if (context.Device.System.NfpDevices[i].State == NfpDeviceState.TagMounted) { byte[] applicationArea = VirtualAmiibo.GetApplicationArea(context.Device.System.NfpDevices[i].AmiiboId); context.Memory.Write(outputPosition, applicationArea); size = (uint)applicationArea.Length; resultCode = ResultCode.Success; } else { resultCode = ResultCode.WrongDeviceState; } } } } if (resultCode != ResultCode.Success) { return(resultCode); } if (size == 0) { return(ResultCode.ApplicationAreaIsNull); } context.ResponseData.Write(size); return(ResultCode.Success); }