public async Task SendMessage(byte[] data, bool force)
        {
            if (_status != RotorStatus.Waiting && !force)
            {
                // drop the data
                System.Diagnostics.Debug.WriteLine("Dropped a packet.");
                return;
            }

            if (_port == null)
            {
                await SetupAsync();

                if (_port == null)
                {
                    return;
                }
            }

            if (!_port.IsOpen)
            {
                try
                {
                    _port.Open();
                }
                catch (Exception)
                {
                    return;
                }
            }

            _status = RotorStatus.Sending;

            byte num_rotor = (byte)data.Length;
            var  send_data = new byte[19]; // zero cleared

            send_data[0] = 0xFA;
            send_data[1] = 0xAF;
            for (int i = 0; i < num_rotor; ++i)
            {
                send_data[2 + i] = data[i];
            }

            byte check_sum = 0;

            for (int i = 0; i < 18; ++i)
            {
                check_sum += send_data[i];
            }

            send_data[18] = check_sum;

            //var send_data = _port.Encoding.GetBytes(builder.ToString());
            await _port.BaseStream.WriteAsync(send_data, 0, send_data.Length);

            await _port.BaseStream.FlushAsync();

            await Task.Delay(_interval); // wait for 10 msec

            _status = RotorStatus.Waiting;
        }
        public async Task SetupAsync()
        {
            if (_status == RotorStatus.Initializing)
            {
                return;
            }

            _status = RotorStatus.Initializing;

            SerialPort port;

            string[] ports = SerialPort.GetPortNames();

            // For Debugging
            foreach (string p in ports)
            {
                System.Diagnostics.Debug.WriteLine(p);
            }

            if (ports.Length <= 0)
            {
                _status = RotorStatus.NotInitialized;
                return;
            }

            if (_port != null && _port.IsOpen)
            {
                try
                {
                    _port.Close();
                }
                catch (Exception)
                {
                    _status = RotorStatus.NotInitialized;
                    return;
                }
            }

            var selected_port_name = ports[0];

            var bluetoothNameToCOMPortNumber = GetBluetoothCOMPorts();

            foreach (var pair in bluetoothNameToCOMPortNumber)
            {
                if (pair.Key.IndexOf(_device_name) != -1)
                {
                    selected_port_name = pair.Value;
                    break;
                }
            }

            // for debugging
            System.Diagnostics.Debug.WriteLine(selected_port_name + " is selected.");

            port = new SerialPort
            {
                PortName  = selected_port_name,
                BaudRate  = 115200,
                Parity    = Parity.None,
                DataBits  = 8,
                StopBits  = StopBits.One,
                Handshake = Handshake.None
            };

            while (true)
            {
                try
                {
                    port.Open();
                    break;
                }
                catch (Exception)
                {
                    await Task.Delay(1000);
                }
            }

            _port   = port;
            _status = RotorStatus.Waiting;
        }