public virtual MtpResponse Execute(ushort code, DataPhase dataPhase, uint[] param, byte[] data = null, bool noReadResponseParam = false) { if (param == null) { param = new uint[5]; } sem.WaitOne(); MtpResponse res; try { if (IsOpened()) { res = MtpOperation.ExecuteCommand(device, code, dataPhase, param, data, noReadResponseParam); } else { Debug.WriteLine("[WpdCommand.Execute] device is null."); res = new MtpResponse((ushort)MtpResponseCode.Error, param, data); } } catch (COMException e) { Debug.WriteLine("[WpdCommand.Execute] COM Error occured. ErrorCode: 0x" + e.ErrorCode.ToString("x")); res = new MtpResponse((ushort)MtpResponseCode.Error, param, data); } finally { sem.Release(); } return(res); }
/// <summary> /// オペレーションを実行する /// </summary> /// <param name="device"></param> /// <returns></returns> internal static MtpResponse ExecuteCommand(PortableDevice device, MtpOperationCode code, uint[] param, byte[] sendData, bool noReadResponseParam) { DataPhase dataPhaseInfo = OperationCode2DataPhase[code]; if (dataPhaseInfo == DataPhase.NoDataPhase) { return(executeNoDataCommand(device, (ushort)code, param, noReadResponseParam)); } else if (dataPhaseInfo == DataPhase.DataReadPhase) { return(executeDataReadCommand(device, (ushort)code, param, noReadResponseParam)); } else { return(executeDataWriteCommand(device, (ushort)code, param, sendData, noReadResponseParam)); } }
/// <summary> /// MTPオペレーションを実行する /// </summary> /// <param name="code"></param> /// <param name="param"></param> /// <returns></returns> public MtpResponse Execute(ushort code, DataPhase dataPhase, uint[] param, byte[] data = null) { if (param == null) { param = new uint[5]; } sem.WaitOne(); MtpResponse res; try { res = MtpOperation.ExecuteCommand(device, code, dataPhase, param, data); } catch (COMException e) { Debug.WriteLine("[WpdCommand.Execute] COM Error occured. ErrorCode: 0x" + e.ErrorCode.ToString("x")); res = new MtpResponse((ushort)MtpResponseCode.Error, param, data); } sem.Release(); return(res); }
/// <summary> /// オペレーションを実行する /// </summary> /// <param name="device"></param> /// <returns></returns> internal static MtpResponse ExecuteCommand(PortableDevice device, ushort code, DataPhase dataPhase, uint[] param, byte[] sendData, bool noReadResponseParam) { if (dataPhase == DataPhase.NoDataPhase) { return(executeNoDataCommand(device, code, param, noReadResponseParam)); } else if (dataPhase == DataPhase.DataReadPhase) { return(executeDataReadCommand(device, code, param, noReadResponseParam)); } else { return(executeDataWriteCommand(device, code, param, sendData, noReadResponseParam)); } }
/// <summary> /// A helper function for writing as many <see cref="DataMessage"/> messsages as required. /// </summary> /// <param name="routingID">Routing id for the message being composed.</param> /// <param name="objectID">ID of the object to which the data belong.</param> /// <param name="packet">Data packet to compose in.</param> /// <param name="progressMarker">Progress or pagination marker.</param> /// <param name="vertices">Mesh vertex array.</param> /// <param name="normals">Mesh normal array. One per vertex or just a single normal to apply to all vertices.</param> /// <param name="indices">Mesh indices.</param> /// <param name="colours">Per vertex colours. See <see cref="Colour"/> for format details.</param> /// <remarks>Call recursively until zero is returned. Packet does not get finalised here.</remarks> public static int WriteData(ushort routingID, uint objectID, PacketBuffer packet, ref uint progressMarker, Vector3[] vertices, Vector3[] normals, int[] indices, UInt32[] colours) { DataMessage msg = new DataMessage(); // Local byte overhead needs to account for the size of sendType, offset and itemCount. // Use a larger value as I haven't got the edge cases quite right yet. const int localByteOverhead = 100; msg.ObjectID = objectID; packet.Reset(routingID, DataMessage.MessageID); msg.Write(packet); uint offset; uint itemCount; ushort sendType; int verticesLength = (vertices != null) ? vertices.Length : 0; int normalsLength = (normals != null) ? normals.Length : 0; int coloursLength = (colours != null) ? colours.Length : 0; int indicesLength = (indices != null) ? indices.Length : 0; DataPhase[] phases = new DataPhase[] { new DataPhase((normalsLength == 1) ? SendDataType.UniformNormal : SendDataType.Normals, normalsLength, (uint index) => { Vector3 n = normals[index]; packet.WriteBytes(BitConverter.GetBytes(n.X), true); packet.WriteBytes(BitConverter.GetBytes(n.Y), true); packet.WriteBytes(BitConverter.GetBytes(n.Z), true); }, 4, 3), new DataPhase(SendDataType.Colours, coloursLength, (uint index) => { packet.WriteBytes(BitConverter.GetBytes(colours[index]), true); }, 4), new DataPhase(SendDataType.Vertices, verticesLength, (uint index) => { Vector3 v = vertices[index]; packet.WriteBytes(BitConverter.GetBytes(v.X), true); packet.WriteBytes(BitConverter.GetBytes(v.Y), true); packet.WriteBytes(BitConverter.GetBytes(v.Z), true); }, 4, 3), new DataPhase(SendDataType.Indices, indicesLength, (uint index) => { packet.WriteBytes(BitConverter.GetBytes(indices[index]), true); }, 4), }; int phaseIndex = 0; uint previousPhaseOffset = 0u; // While progressMarker is greater than or equal to the sum of the previous phase counts and the current phase count. // Also terminate of out of phases. while (phaseIndex < phases.Length && progressMarker >= previousPhaseOffset + phases[phaseIndex].ItemCount) { previousPhaseOffset += phases[phaseIndex].ItemCount; ++phaseIndex; } bool done = false; // Check if we have anything to send. if (phaseIndex < phases.Length) { DataPhase phase = phases[phaseIndex]; // Send part of current phase. // Estimate element count limit. int maxItemCount = MeshBase.EstimateTransferCount(phase.DataSizeBytes * phase.TupleSize, 0, DataMessage.Size + localByteOverhead); offset = progressMarker - previousPhaseOffset; itemCount = (uint)Math.Min(phase.ItemCount - offset, maxItemCount); sendType = (ushort)((int)phase.Type | (int)SendDataType.ExpectEnd); packet.WriteBytes(BitConverter.GetBytes(sendType), true); packet.WriteBytes(BitConverter.GetBytes(offset), true); packet.WriteBytes(BitConverter.GetBytes(itemCount), true); for (uint i = offset; i < offset + itemCount; ++i) { phase.WriteElement(i); } progressMarker += itemCount; } else { // Either all done or no data to send. // In the latter case, we need to populate the message anyway. offset = itemCount = 0; sendType = (int)SendDataType.ExpectEnd | (int)SendDataType.End; packet.WriteBytes(BitConverter.GetBytes(sendType), true); packet.WriteBytes(BitConverter.GetBytes(offset), true); packet.WriteBytes(BitConverter.GetBytes(itemCount), true); done = true; } // Return 1 while there is more data to process. return((!done) ? 1 : 0); }