public async Task <bool> SendMqttMessageAsync(string topic, byte[] data, CancellationToken cancellationToken) { if (data.Length > 1548) { throw new Exception("Message is too long!"); } if (_module.CurrentBinaryWriteTask != null) { throw new Exception("Cannot create another binary write task when one is already queued!"); } var command = $"AT+QMTPUB={CurrentTcpConnectId},{_currentMessageId},{DefaultQOS},{(ShouldServerRetain ? 1 : 0)},\"{topic}\""; _currentMessageId++; _module.WriteLine(command); var waitTaskSource = new TaskCompletionSource <bool>(); _module.CurrentBinaryWriteTask = waitTaskSource; var waitTaskResult = await waitTaskSource.Task; _module.CurrentBinaryWriteTask = null; //very important! if (waitTaskResult) { _module.BaseSerialPort.Write(data, 0, data.Length); _module.BaseSerialPort.Write("\u001A"); } else { throw new Exception("Waiting for binary read signal failed!"); } var waitResponseSource = new TaskCompletionSource <CommandResult>(); _module.AtCommandResultQueue.AddFirst(waitResponseSource); //push to top of queue, since we should be there anyways and we had received the > char var result = await waitResponseSource.Task; result.ThrowIfError(); return(!result.WasCMEError && result.Result == ATCommandResultCode.OK); }