private async Task SendRequestAsync(FidoHidMsgType msgType, byte[] data = null) { if (data == null) { data = new byte[0]; } var size = data.Length; var payloadData = data.Take(HidReportSize - 7).ToArray(); var payloadBuilder = new ByteArrayBuilder(); payloadBuilder.Append(_channelId); payloadBuilder.Append((byte)msgType); payloadBuilder.Append((byte)(size >> 8 & 0xff)); payloadBuilder.Append((byte)(size & 0xff)); payloadBuilder.Append(payloadData); payloadBuilder.AppendZerosTill(HidReportSize); var report = _hidDevice.CreateReport(); report.Data = payloadBuilder.GetBytes(); if (!await _hidDevice.WriteReportAsync(report, HidTimeoutMs).ConfigureAwait(false)) { throw new FidoException(FidoError.InterruptedIO, "Error writing to token"); } var remainingData = data.Skip(HidReportSize - 7).ToArray(); var seq = 0; while (remainingData.Length > 0) { payloadData = remainingData.Take(HidReportSize - 5).ToArray(); payloadBuilder.Clear(); payloadBuilder.Append(_channelId); payloadBuilder.Append((byte)(0x7f & seq)); payloadBuilder.Append(payloadData); payloadBuilder.AppendZerosTill(HidReportSize); report = _hidDevice.CreateReport(); report.Data = payloadBuilder.GetBytes(); if (!await _hidDevice.WriteReportAsync(report, HidTimeoutMs).ConfigureAwait(false)) { throw new FidoException(FidoError.InterruptedIO, "Error writing to token"); } remainingData = remainingData.Skip(HidReportSize - 5).ToArray(); seq++; } }
public static byte[] GenerateRequestMessage(string deviceAddr = "") { _buffer.Clear(); _buffer.Append(Constants.StartMessage); _buffer.Append(Constants.Request); if (!String.IsNullOrEmpty(deviceAddr)) { _buffer.Append(deviceAddr); } _buffer.Append(Constants.EndMessage); _buffer.Append(Constants.CR); _buffer.Append(Constants.LF); return(_buffer.ToArray()); }
void AppendString(FormatOptions options, bool allowAtom, ByteArrayBuilder builder, string value) { byte[] buf; switch (GetStringType(Engine, value, allowAtom)) { case ImapStringType.Literal: var literal = Encoding.UTF8.GetBytes(value); var plus = CanUseNonSynchronizedLiteral(Engine, literal.Length); var length = literal.Length.ToString(CultureInfo.InvariantCulture); buf = Encoding.ASCII.GetBytes(length); builder.Append((byte)'{'); builder.Append(buf, 0, buf.Length); if (plus) { builder.Append((byte)'+'); } builder.Append((byte)'}'); builder.Append((byte)'\r'); builder.Append((byte)'\n'); if (plus) { builder.Append(literal, 0, literal.Length); } else { parts.Add(new ImapCommandPart(builder.ToArray(), new ImapLiteral(options, literal))); builder.Clear(); } break; case ImapStringType.QString: buf = Encoding.UTF8.GetBytes(MimeUtils.Quote(value)); builder.Append(buf, 0, buf.Length); break; case ImapStringType.Atom: buf = Encoding.UTF8.GetBytes(value); builder.Append(buf, 0, buf.Length); break; case ImapStringType.Nil: builder.Append(Nil, 0, Nil.Length); break; } }
/// <summary> /// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapCommand"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="MailKit.Net.Imap.ImapCommand"/>. /// </remarks> /// <param name="engine">The IMAP engine that will be sending the command.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="folder">The IMAP folder that the command operates on.</param> /// <param name="options">The formatting options.</param> /// <param name="format">The command format.</param> /// <param name="args">The command arguments.</param> public ImapCommand(ImapEngine engine, CancellationToken cancellationToken, ImapFolder folder, FormatOptions options, string format, params object[] args) { UntaggedHandlers = new Dictionary <string, ImapUntaggedHandler> (StringComparer.OrdinalIgnoreCase); Logout = format.Equals("LOGOUT\r\n", StringComparison.Ordinal); RespCodes = new List <ImapResponseCode> (); CancellationToken = cancellationToken; Response = ImapCommandResponse.None; Status = ImapCommandStatus.Created; Engine = engine; Folder = folder; using (var builder = new ByteArrayBuilder(1024)) { byte[] buf, utf8 = new byte[8]; int argc = 0; string str; for (int i = 0; i < format.Length; i++) { if (format[i] == '%') { switch (format[++i]) { case '%': // a literal % builder.Append((byte)'%'); break; case 'd': // an integer str = ((int)args[argc++]).ToString(CultureInfo.InvariantCulture); buf = Encoding.ASCII.GetBytes(str); builder.Append(buf, 0, buf.Length); break; case 'u': // an unsigned integer str = ((uint)args[argc++]).ToString(CultureInfo.InvariantCulture); buf = Encoding.ASCII.GetBytes(str); builder.Append(buf, 0, buf.Length); break; case 's': str = (string)args[argc++]; buf = Encoding.ASCII.GetBytes(str); builder.Append(buf, 0, buf.Length); break; case 'F': // an ImapFolder var utf7 = ((ImapFolder)args[argc++]).EncodedName; AppendString(options, true, builder, utf7); break; case 'L': // a MimeMessage or a byte[] var arg = args[argc++]; ImapLiteral literal; byte[] prefix; if (arg is MimeMessage message) { prefix = options.International ? UTF8LiteralTokenPrefix : LiteralTokenPrefix; literal = new ImapLiteral(options, message, UpdateProgress); } else { literal = new ImapLiteral(options, (byte[])arg); prefix = LiteralTokenPrefix; } var length = literal.Length; bool wait = true; builder.Append(prefix, 0, prefix.Length); buf = Encoding.ASCII.GetBytes(length.ToString(CultureInfo.InvariantCulture)); builder.Append(buf, 0, buf.Length); if (CanUseNonSynchronizedLiteral(Engine, length)) { builder.Append((byte)'+'); wait = false; } builder.Append(LiteralTokenSuffix, 0, LiteralTokenSuffix.Length); totalSize += length; parts.Add(new ImapCommandPart(builder.ToArray(), literal, wait)); builder.Clear(); if (prefix == UTF8LiteralTokenPrefix) { builder.Append((byte)')'); } break; case 'S': // a string which may need to be quoted or made into a literal AppendString(options, true, builder, (string)args[argc++]); break; case 'Q': // similar to %S but string must be quoted at a minimum AppendString(options, false, builder, (string)args[argc++]); break; default: throw new FormatException(); } } else if (format[i] < 128) { builder.Append((byte)format[i]); } else { int nchars = char.IsSurrogate(format[i]) ? 2 : 1; int nbytes = Encoding.UTF8.GetBytes(format, i, nchars, utf8, 0); builder.Append(utf8, 0, nbytes); i += nchars - 1; } } parts.Add(new ImapCommandPart(builder.ToArray(), null)); } }