unit main;

interface

{$I BF.inc}

uses
  Forms, BFAuthenticator, BFAPI, Classes, BFBase, Controls,
  ExtCtrls, jpeg, StdCtrls, ComCtrls, BFDiscovery, BFControls,
  BFBluetoothCOMPortCreator, BFClients, BFClient, BFSerialPortClient,
  BFATCommandClient, BFGSMModemClient, BFSerialEventsClient, BFOBEXClient,
  BFObjectPushClient, Dialogs, Buttons, BFXPMan, BFFileTransferClient,
  BFServers, BFServer, BFOBEXServer, BFObjectPushServer,
  BFBluetoothMassSender, BFBluetoothAudio;

type
  TDevFileRecord = record
    Addr: string;
    Index: Integer;
  end;

  TfmMain = class(TForm)
    BFAPIInfo: TBFAPIInfo;
    BFAuthenticator: TBFAuthenticator;
    imLogo: TImage;
    laDemo: TLabel;
    pcMain: TPageControl;
    tsSystem: TTabSheet;
    laTransportsTitle: TLabel;
    cbBluetooth: TCheckBox;
    cbIrDA: TCheckBox;
    cbSerialPorts: TCheckBox;
    laBluetoothAPI: TLabel;
    laAuthentication: TLabel;
    cbAuthenticationEnable: TCheckBox;
    cbUseDefaultPIN: TCheckBox;
    laDefaultPIN: TLabel;
    edDefaultPIN: TEdit;
    tsBluetoothDiscovery: TTabSheet;
    pcBluetooth: TPageControl;
    tsBluetoothDevices: TTabSheet;
    tsRadios: TTabSheet;
    tsCOMPorts: TTabSheet;
    paBluetoothDevices: TPanel;
    lvBluetoothDevices: TListView;
    spBluetoothDevices: TSplitter;
    lbBluetoothDevices: TListBox;
    btBluetoothDiscovery: TButton;
    btBluetoothNonBlockingDiscovery: TButton;
    btBluetoothSelectDevice: TButton;
    btBluetoothStartMonitoring: TButton;
    btBluetoothStopMonitoring: TButton;
    btBluetoothDeviceRename: TButton;
    btBluetoothPair: TButton;
    btBluetoothUnpair: TButton;
    BFBluetoothDiscovery: TBFBluetoothDiscovery;
    cbBluetoothFast: TCheckBox;
    cbBluetoothNeedServices: TCheckBox;
    cbBluetoothAlwaysNew: TCheckBox;
    lvPorts: TListView;
    paCOMPorts: TPanel;
    btEnumPorts: TButton;
    paRadios: TPanel;
    btEnumRadios: TButton;
    btRenameRadios: TButton;
    btDiscoverable: TButton;
    btConnectable: TButton;
    lvRadios: TListView;
    tsIrDADiscovery: TTabSheet;
    lvIrDA: TListView;
    spIrDA: TSplitter;
    lbIrDA: TListBox;
    paIrDADiscovery: TPanel;
    btIrDADiscovery: TButton;
    btIrDANonBlocking: TButton;
    btIrDASelect: TButton;
    btIrDAStart: TButton;
    btIrDAStop: TButton;
    cbIrDAAlwaysNew: TCheckBox;
    BFIrDADiscovery: TBFIrDADiscovery;
    tsControls: TTabSheet;
    BFCharge: TBFCharge;
    BFSignal: TBFSignal;
    cbFlashCharge: TCheckBox;
    laChargeFlashLevel: TLabel;
    edChargeFlashLevel: TEdit;
    laChargeFlashInterval: TLabel;
    edChargeFlashInterval: TEdit;
    laChargeLevel: TLabel;
    edChargeLevel: TEdit;
    laSignalLevel: TLabel;
    edSignalLevel: TEdit;
    tsCOMPortCreator: TTabSheet;
    BFBluetoothCOMPortCreator: TBFBluetoothCOMPortCreator;
    btCreateCOM: TButton;
    cbDestroyCOM: TButton;
    lbCOMPort: TListBox;
    BFSerialPortClient: TBFSerialPortClient;
    tsSerialPort: TTabSheet;
    btOpenSerial: TButton;
    btCloseSerial: TButton;
    meSerial: TMemo;
    BFGSMModemClient: TBFGSMModemClient;
    tsSerialEvents: TTabSheet;
    BFSerialEventsClient: TBFSerialEventsClient;
    btCloseEvents: TButton;
    btOpenEvents: TButton;
    meEvents: TMemo;
    tsGSMModem: TTabSheet;
    pcGSMModem: TPageControl;
    paGSMModem: TPanel;
    tsPhoneInfo: TTabSheet;
    laCharge: TLabel;
    btGSMOpen: TButton;
    btGSMClose: TButton;
    GSMCharge: TBFCharge;
    GSMSignal: TBFSignal;
    laNetworkSignal: TLabel;
    laClockTitle: TLabel;
    laClock: TLabel;
    laIMEITitle: TLabel;
    laIMEI: TLabel;
    laIMSITitle: TLabel;
    laIMSI: TLabel;
    laManuTitle: TLabel;
    laManu: TLabel;
    laModelTitle: TLabel;
    laModel: TLabel;
    laFirmwareTitle: TLabel;
    laFirmware: TLabel;
    tsKeyPad: TTabSheet;
    tsSMS: TTabSheet;
    pcSMS: TPageControl;
    tsSMSList: TTabSheet;
    lvSMS: TListView;
    tsSMSSettings: TTabSheet;
    paSMSListTools: TPanel;
    btReadSMS: TButton;
    btDeleteSMS: TButton;
    laServiceCenter: TLabel;
    edSCANumber: TEdit;
    laRDMemory: TLabel;
    cbRDMemory: TComboBox;
    laWSMemory: TLabel;
    cbWSMemory: TComboBox;
    laRecMemory: TLabel;
    cbRecMemory: TComboBox;
    btReadSettings: TButton;
    btWriteSettings: TButton;
    tsSendSMS: TTabSheet;
    laPhone: TLabel;
    edPhone: TEdit;
    cbFlash: TCheckBox;
    cbReport: TCheckBox;
    meSMS: TMemo;
    btSendSMS: TButton;
    btSaveSMS: TButton;
    btSendSaved: TButton;
    cbNeedrepSaved: TCheckBox;
    tsObjectPushClient: TTabSheet;
    BFObjectPushClient: TBFObjectPushClient;
    pbOPP: TProgressBar;
    btOPPSendFile: TButton;
    btOPPAbort: TButton;
    OpenDialog: TOpenDialog;
    sbLeftBt: TSpeedButton;
    sbRightBt: TSpeedButton;
    sbUp: TSpeedButton;
    sbLeft: TSpeedButton;
    sbRight: TSpeedButton;
    sbMiddle: TSpeedButton;
    sbDown: TSpeedButton;
    snAnswer: TSpeedButton;
    snEnd: TSpeedButton;
    sb1: TSpeedButton;
    sb2: TSpeedButton;
    sb3: TSpeedButton;
    sb4: TSpeedButton;
    sb5: TSpeedButton;
    sb6: TSpeedButton;
    sb7: TSpeedButton;
    sb8: TSpeedButton;
    sb9: TSpeedButton;
    sbAs: TSpeedButton;
    sb0: TSpeedButton;
    sbNum: TSpeedButton;
    lbKeypadEvents: TListBox;
    tsGSMPhonebook: TTabSheet;
    BFXPMan: TBFXPMan;
    tsFileTransferClient: TTabSheet;
    paFileTransfer: TPanel;
    lvFileTransfer: TListView;
    btFSConnect: TButton;
    btFSDisconnect: TButton;
    btFSCreateFolder: TButton;
    btFSUpload: TButton;
    btFSDownload: TButton;
    btFSAbort: TButton;
    btFSDir: TButton;
    btFSSetPath: TButton;
    pbFS: TProgressBar;
    BFFileTransferClient: TBFFileTransferClient;
    btFSRoot: TButton;
    btFSUp: TButton;
    btFSDelete: TButton;
    SaveDialog: TSaveDialog;
    tsChat: TTabSheet;
    BFClient: TBFClient;
    BFServer: TBFServer;
    pcChat: TPageControl;
    tsChatServer: TTabSheet;
    tsChatClient: TTabSheet;
    btChatServerListen: TButton;
    btChatServerClose: TButton;
    edChatServerText: TEdit;
    btChatServerSend: TButton;
    lbChatServer: TListBox;
    btChatClientOpen: TButton;
    btChatClientClose: TButton;
    btChatClientSend: TButton;
    edChatClientText: TEdit;
    lbChatClient: TListBox;
    BFObjectPushServer: TBFObjectPushServer;
    BFObjectPushServerIrDA: TBFObjectPushServer;
    tsOPServer: TTabSheet;
    btOPPServerListen: TButton;
    btOPPServerClose: TButton;
    lbOPPServer: TListBox;
    tsMassSender: TTabSheet;
    BFBluetoothMassSender: TBFBluetoothMassSender;
    btMSStart: TButton;
    btMSStop: TButton;
    lbMass: TListBox;
    laSMSEncoding: TLabel;
    cbSMSEncoding: TComboBox;
    paPhonebook: TPanel;
    btGSMPhoneBookRead: TButton;
    cbPhoneBooks: TComboBox;
    btSetPhoneBook: TButton;
    btGetPhoneBook: TButton;
    btWritePhonebook: TButton;
    lvGSMPhoneBook: TListView;
    paPhoneBookEdit: TPanel;
    edName: TEdit;
    edNumber: TEdit;
    btAddRecord: TButton;
    btUpdateRecord: TButton;
    btDeleteRecord: TButton;
    pbPhonebook: TProgressBar;
    laVer: TLabel;
    lbFiles: TListBox;
    btAddFile: TButton;
    btDeleteFile: TButton;
    btClearFiles: TButton;
    btRedetect: TButton;
    cbBlueSoleil: TCheckBox;
    cbMicrosoft: TCheckBox;
    cbToshiba: TCheckBox;
    cbWidComm: TCheckBox;
    pbOBServer: TProgressBar;
    cbSendvCard: TCheckBox;
    cbActiveSync: TCheckBox;
    tsAudio: TTabSheet;
    BFBluetoothAudio: TBFBluetoothAudio;
    btOpenAudio: TButton;
    btCloseAudio: TButton;
    btCheckDevice: TButton;
    procedure FormCreate(Sender: TObject);
    procedure cbBluetoothClick(Sender: TObject);
    procedure cbUseDefaultPINClick(Sender: TObject);
    procedure BFAuthenticatorPINRequest(Sender: TObject; DeviceAddress: string; var PIN: String);
    procedure cbAuthenticationEnableClick(Sender: TObject);
    procedure BFBluetoothDiscoveryDeviceFound(Sender: TObject; Device: TBFBluetoothDevice);
    procedure BFBluetoothDiscoveryDeviceLost(Sender: TObject; Device: TBFBluetoothDevice);
    procedure BFBluetoothDiscoveryStartMonitoring(Sender: TObject);
    procedure BFBluetoothDiscoveryStartSearch(Sender: TObject);
    procedure BFBluetoothDiscoveryStopMonitoring(Sender: TObject);
    procedure BFBluetoothDiscoveryStopSearch(Sender: TObject);
    procedure BFBluetoothDiscoveryComplete(Sender: TObject; Devices: TBFBluetoothDevices);
    procedure btBluetoothDiscoveryClick(Sender: TObject);
    procedure btBluetoothNonBlockingDiscoveryClick(Sender: TObject);
    procedure btBluetoothSelectDeviceClick(Sender: TObject);
    procedure btBluetoothStartMonitoringClick(Sender: TObject);
    procedure btBluetoothStopMonitoringClick(Sender: TObject);
    procedure btBluetoothDeviceRenameClick(Sender: TObject);
    procedure btBluetoothUnpairClick(Sender: TObject);
    procedure btBluetoothPairClick(Sender: TObject);
    procedure btEnumPortsClick(Sender: TObject);
    procedure btEnumRadiosClick(Sender: TObject);
    procedure btDiscoverableClick(Sender: TObject);
    procedure btConnectableClick(Sender: TObject);
    procedure btRenameRadiosClick(Sender: TObject);
    procedure BFIrDADiscoveryComplete(Sender: TObject; Devices: TBFIrDADevices);
    procedure btIrDADiscoveryClick(Sender: TObject);
    procedure btIrDANonBlockingClick(Sender: TObject);
    procedure btIrDASelectClick(Sender: TObject);
    procedure btIrDAStartClick(Sender: TObject);
    procedure btIrDAStopClick(Sender: TObject);
    procedure BFIrDADiscoveryDeviceFound(Sender: TObject; Device: TBFIrDADevice);
    procedure BFIrDADiscoveryDeviceLost(Sender: TObject; Device: TBFIrDADevice);
    procedure BFIrDADiscoveryStartMonitoring(Sender: TObject);
    procedure BFIrDADiscoveryStartSearch(Sender: TObject);
    procedure BFIrDADiscoveryStopMonitoring(Sender: TObject);
    procedure BFIrDADiscoveryStopSearch(Sender: TObject);
    procedure cbFlashChargeClick(Sender: TObject);
    procedure edChargeFlashLevelChange(Sender: TObject);
    procedure edChargeFlashIntervalChange(Sender: TObject);
    procedure edChargeLevelChange(Sender: TObject);
    procedure edSignalLevelChange(Sender: TObject);
    procedure btCreateCOMClick(Sender: TObject);
    procedure cbDestroyCOMClick(Sender: TObject);
    procedure btOpenSerialClick(Sender: TObject);
    procedure btCloseSerialClick(Sender: TObject);
    procedure BFSerialPortClientDisconnect(Sender: TObject);
    procedure BFSerialPortClientData(Sender: TObject);
    procedure meSerialKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure btOpenEventsClick(Sender: TObject);
    procedure btCloseEventsClick(Sender: TObject);
    procedure BFSerialEventsClientDisconnect(Sender: TObject);
    procedure BFSerialEventsClientEvent(Sender: TObject; EventData: String);
    procedure btGSMOpenClick(Sender: TObject);
    procedure btGSMCloseClick(Sender: TObject);
    procedure BFGSMModemClientDisconnect(Sender: TObject);
    procedure btReadSettingsClick(Sender: TObject);
    procedure btWriteSettingsClick(Sender: TObject);
    procedure btReadSMSClick(Sender: TObject);
    procedure btDeleteSMSClick(Sender: TObject);
    procedure BFGSMModemClientNew(Sender: TObject; AType: TBFSMSType; AMemory: TBFSMSMemory; AIndex: Integer);
    procedure btSendSMSClick(Sender: TObject);
    procedure btSaveSMSClick(Sender: TObject);
    procedure btSendSavedClick(Sender: TObject);
    procedure btOPPAbortClick(Sender: TObject);
    procedure btOPPSendFileClick(Sender: TObject);
    procedure BFObjectPushClientProgress(Sender: TObject; AName: String; Index, Count, Position, Size: Integer; var Abort: Boolean);
    procedure BFGSMModemClientDown(Sender: TObject; Key: TBFKey);
    procedure BFGSMModemClientUp(Sender: TObject; Key: TBFKey);
    procedure sbLeftBtClick(Sender: TObject);
    procedure sbRightBtClick(Sender: TObject);
    procedure sbUpClick(Sender: TObject);
    procedure sbLeftClick(Sender: TObject);
    procedure sbRightClick(Sender: TObject);
    procedure sbDownClick(Sender: TObject);
    procedure sbMiddleClick(Sender: TObject);
    procedure snAnswerClick(Sender: TObject);
    procedure snEndClick(Sender: TObject);
    procedure sb1Click(Sender: TObject);
    procedure sb2Click(Sender: TObject);
    procedure sb3Click(Sender: TObject);
    procedure sb4Click(Sender: TObject);
    procedure sb5Click(Sender: TObject);
    procedure sb6Click(Sender: TObject);
    procedure sb7Click(Sender: TObject);
    procedure sb8Click(Sender: TObject);
    procedure sb9Click(Sender: TObject);
    procedure sb0Click(Sender: TObject);
    procedure sbAsClick(Sender: TObject);
    procedure sbNumClick(Sender: TObject);
    procedure btGSMPhoneBookReadClick(Sender: TObject);
    procedure btGetPhoneBookClick(Sender: TObject);
    procedure btSetPhoneBookClick(Sender: TObject);
    procedure BFFileTransferClientProgress(Sender: TObject; AName: String; Index, Count, Position, Size: Integer; var Abort: Boolean);
    procedure btFSConnectClick(Sender: TObject);
    procedure btFSDisconnectClick(Sender: TObject);
    procedure btFSUploadClick(Sender: TObject);
    procedure btFSDownloadClick(Sender: TObject);
    procedure btFSDirClick(Sender: TObject);
    procedure btFSCreateFolderClick(Sender: TObject);
    procedure btFSSetPathClick(Sender: TObject);
    procedure btFSAbortClick(Sender: TObject);
    procedure btFSRootClick(Sender: TObject);
    procedure btFSUpClick(Sender: TObject);
    procedure btFSDeleteClick(Sender: TObject);
    procedure btChatServerListenClick(Sender: TObject);
    procedure btChatServerCloseClick(Sender: TObject);
    procedure btChatServerSendClick(Sender: TObject);
    procedure BFServerConnect(Sender: TObject);
    procedure BFServerDisconnect(Sender: TObject);
    procedure BFServerData(Sender: TObject; Data: TBFByteArray);
    procedure btChatClientOpenClick(Sender: TObject);
    procedure btChatClientCloseClick(Sender: TObject);
    procedure btChatClientSendClick(Sender: TObject);
    procedure BFClientData(Sender: TObject);
    procedure BFClientDisconnect(Sender: TObject);
    procedure btOPPServerListenClick(Sender: TObject);
    procedure btOPPServerCloseClick(Sender: TObject);
    procedure BFObjectPushServerConnect(Sender: TObject);
    procedure BFObjectPushServerDisconnect(Sender: TObject);
    procedure BFObjectPushServerObject(Sender: TObject; AName: String; AObject: TBFByteArray);
    procedure BFObjectPushServerIrDAConnect(Sender: TObject);
    procedure BFObjectPushServerIrDADisconnect(Sender: TObject);
    procedure BFObjectPushServerIrDAObject(Sender: TObject; AName: String; AObject: TBFByteArray);
    procedure cbSMSEncodingChange(Sender: TObject);
    procedure btAddRecordClick(Sender: TObject);
    procedure btUpdateRecordClick(Sender: TObject);
    procedure btWritePhonebookClick(Sender: TObject);
    procedure btDeleteRecordClick(Sender: TObject);
    procedure lvGSMPhoneBookDblClick(Sender: TObject);
    procedure BFGSMModemClientPhonebookProgress(Sender: TObject; AIndex, ATotal: Integer);
    procedure btClearFilesClick(Sender: TObject);
    procedure btDeleteFileClick(Sender: TObject);
    procedure btAddFileClick(Sender: TObject);
    procedure BFFileTransferClientDisconnect(Sender: TObject);
    procedure BFObjectPushClientDisconnect(Sender: TObject);
    procedure btRedetectClick(Sender: TObject);
    procedure cbWidCommClick(Sender: TObject);
    procedure BFObjectPushServerIrDAProgress(Sender: TObject; AName: String; APosition, ASize: Cardinal; var AAbort: Boolean);
    procedure cbSendvCardClick(Sender: TObject);
    procedure BFBluetoothMassSenderAcceptDevice(Sender: TObject; Device: TBFBluetoothDevice; var Accept: Boolean);
    procedure BFBluetoothMassSenderDiscoveryComplete(Sender: TObject; Count: Integer);
    procedure BFBluetoothMassSenderDiscoveryStarted(Sender: TObject);
    procedure BFBluetoothMassSenderNeedFile(Sender: TObject; Device: TBFBluetoothDevice; var FileName: String; var More: Boolean);
    procedure BFBluetoothMassSenderSendComplete(Sender: TObject; Device: TBFBluetoothDevice; Status: TBFMSSendResult);
    procedure BFBluetoothMassSenderSendFileComplete(Sender: TObject; Device: TBFBluetoothDevice; FileName: String; Status: TBFMSSendResult);
    procedure BFBluetoothMassSenderSendFileStart(Sender: TObject; Device: TBFBluetoothDevice; FileName: String);
    procedure BFBluetoothMassSenderSendStart(Sender: TObject; Device: TBFBluetoothDevice);
    procedure BFBluetoothMassSenderSendvCardComplete(Sender: TObject; Device: TBFBluetoothDevice; Status: TBFMSSendResult);
    procedure BFBluetoothMassSenderSendvCardStart(Sender: TObject; Device: TBFBluetoothDevice);
    procedure BFBluetoothMassSenderStarted(Sender: TObject);
    procedure BFBluetoothMassSenderStopped(Sender: TObject);
    procedure btMSStartClick(Sender: TObject);
    procedure btMSStopClick(Sender: TObject);
    procedure cbActiveSyncClick(Sender: TObject);
    procedure btCloseAudioClick(Sender: TObject);
    procedure btOpenAudioClick(Sender: TObject);
    procedure btCheckDeviceClick(Sender: TObject);

  private
    FAbort: Boolean;
    FDevFileRecords: array [0..255] of TDevFileRecord;
    FDevRecordNdx: Integer;

    function SelectBluetoothDevice: TBFBluetoothDevice;
    function SelectBluetoothRadio: TBFBluetoothRadio;

    procedure DetectBluetoothAPI;
    procedure DetectTransports;
    procedure ShowBluetoothDevice(Device: TBFBluetoothDevice);
    procedure ShowBluetoothDevices(Devices: TBFBluetoothDevices);
    procedure ShowIrDADevice(Device: TBFIrDADevice);
    procedure ShowIrDADevices(Devices: TBFIrDADevices);
  end;

var
  fmMain: TfmMain = nil;

implementation

uses
  BFAbout, SysUtils, Windows, BFvCard{$IFDEF DELPHI5}, ComObj{$ENDIF};

{$R *.dfm}

procedure TfmMain.DetectTransports;
begin
  with BFAPIInfo do begin
    cbBluetooth.Checked := atBluetooth in Transports;
    cbIrDA.Checked := atIrDA in Transports;
    cbSerialPorts.Checked := atCOM in Transports;
  end;
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  laVer.Caption := BFAbout.VERSION;

  pcMain.ActivePage := tsSystem;
  pcBluetooth.ActivePage := tsBluetoothDevices;
  pcGSMModem.ActivePage := tsPhoneInfo;
  pcSMS.ActivePage := tsSMSList;
  pcChat.ActivePage := tsChatServer;

  laClock.Caption := '';
  laIMEI.Caption := '';
  laIMSI.Caption := '';
  laManu.Caption := '';
  laModel.Caption := '';
  laFirmware.Caption := '';

  DetectBluetoothAPI;
  DetectTransports;

  with BFClient do begin
    with BluetoothTransport do begin
      Authentication := False;
      Encryption := False;
      //ServiceUUID := StringToGUID('{8D8279AF-162B-4B7F-8F11-506C7276F4E2}');
      //Service := 'Bluetooth Framework Chat';
      ServiceUUID :=   StringToGUID('{16D80E64-9DC4-4A6A-B2FE-3C857AB009D2}');
      Service := 'bluepolling';
    end;

    Transport := atBluetooth;
  end;

  with BFServer do begin
    with BluetoothTransport do begin
      Authentication := False;
      Encryption := False;
      ServiceUUID := StringToGUID('{8D8279AF-162B-4B7F-8F11-506C7276F4E2}');
      Service := 'Bluetooth Framework Chat';
    end;

    Transport := atBluetooth;
  end;

  if (baWinSock in BFAPIInfo.BluetoothAPIs) or (baBlueSoleil in BFAPIInfo.BluetoothAPIs) then begin
    cbAuthenticationEnable.Checked := True;
    cbUseDefaultPIN.Checked := True;
  end;

  cbActiveSyncClick(cbActiveSync);
end;

procedure TfmMain.cbBluetoothClick(Sender: TObject);
begin
  DetectTransports;
end;

procedure TfmMain.DetectBluetoothAPI;
begin
  with BFAPIInfo do begin
    cbBlueSoleil.Checked := baBlueSoleil in BluetoothAPIs;
    cbMicrosoft.Checked := baWinSock in BluetoothAPIs;
    cbToshiba.Checked := baToshiba in BluetoothAPIs;
    cbWidComm.Checked := baWidComm in BluetoothAPIs;
  end;
end;

procedure TfmMain.cbUseDefaultPINClick(Sender: TObject);
begin
  if cbUseDefaultPIN.Checked then begin
    laDefaultPIN.Enabled := True;
    edDefaultPIN.Enabled := True;

    BFAuthenticator.OnPINRequest := BFAuthenticatorPINRequest;

  end else begin
    laDefaultPIN.Enabled := False;
    edDefaultPIN.Enabled := False;

    BFAuthenticator.OnPINRequest := nil;
  end;
end;

procedure TfmMain.BFAuthenticatorPINRequest(Sender: TObject; DeviceAddress: string; var PIN: String);
begin
  PIN := edDefaultPIN.Text;
end;

procedure TfmMain.cbAuthenticationEnableClick(Sender: TObject);
begin
  if cbAuthenticationEnable.Checked then begin
    BFAuthenticator.Open;

    cbUseDefaultPIN.Enabled := True;

  end else begin
    BFAuthenticator.Close;

    with cbUseDefaultPIN do begin
      Checked := False;
      Enabled := False;
    end;

    cbUseDefaultPINClick(cbUseDefaultPIN);
  end;
end;

procedure TfmMain.BFBluetoothDiscoveryDeviceFound(Sender: TObject; Device: TBFBluetoothDevice);
begin
  with Device do lbBluetoothDevices.Items.Add('Device found: ' + Address + ' ' + Name);
end;

procedure TfmMain.BFBluetoothDiscoveryDeviceLost(Sender: TObject; Device: TBFBluetoothDevice);
begin
  with Device do lbBluetoothDevices.Items.Add('Device lost: ' + Address + ' ' + Name);
end;

procedure TfmMain.BFBluetoothDiscoveryStartMonitoring(Sender: TObject);
begin
  lbBluetoothDevices.Items.Add('Monitoring started');
end;

procedure TfmMain.BFBluetoothDiscoveryStartSearch(Sender: TObject);
begin
  lbBluetoothDevices.Items.Add('Search started');
end;

procedure TfmMain.BFBluetoothDiscoveryStopMonitoring(Sender: TObject);
begin
  lbBluetoothDevices.Items.Add('Monitoring stopped');
end;

procedure TfmMain.BFBluetoothDiscoveryStopSearch(Sender: TObject);
begin
  lbBluetoothDevices.Items.Add('Search stopped');
end;

procedure TfmMain.BFBluetoothDiscoveryComplete(Sender: TObject; Devices: TBFBluetoothDevices);
begin
  lbBluetoothDevices.Items.Add('Non blocking discovery complete. Found: ' + IntToStr(Devices.Count) + ' device(s)');

  ShowBluetoothDevices(Devices);
end;

procedure TfmMain.ShowBluetoothDevices(Devices: TBFBluetoothDevices);
var
  Loop: Integer;
  Device: TBFBluetoothDevice;
begin
  with lvBluetoothDevices do
    with Items do begin
      BeginUpdate;
      for Loop := 0 to Count - 1 do
        with Items[Loop] do
          if Assigned(Data) then
            TBFBluetoothDevice(Data).Free;

      Clear;

      if Assigned(Devices) then
        for Loop := 0 to Devices.Count - 1 do begin
          Device := Devices[Loop];

          ShowBluetoothDevice(Device);
        end;

      EndUpdate;
    end;
end;

procedure TfmMain.ShowBluetoothDevice(Device: TBFBluetoothDevice);
var
  AService: TBFBluetoothService;
  AServices: TBFBluetoothServices;
  Loop: Integer;
  NewDevice: TBFBluetoothDevice;
begin
  if Assigned(Device) then begin
    NewDevice := TBFBluetoothDevice.Create(nil);
    NewDevice.Assign(Device);

    with NewDevice, lvBluetoothDevices.Items do begin
      with Add do begin
        Caption := Address;

        with SubItems do begin
          Add(BFBoolToStr(Authenticated));
          Add('0x' + IntToHex(BTAddress, 12));
          Add(BFBoolToStr(Connected));
          Add('0x' + IntToHex(ClassOfDevice, 8));
          Add(ClassOfDeviceName);
          if LastSeen = 0 then
            Add(' ')
          else
            Add(DateTimeToStr(LastSeen));
          if LastUsed = 0 then
            Add(' ')
          else
            Add(DateTimeToStr(LastUsed));
          Add(Name);
          Add(BFBoolToStr(Remembered));
          Add(Radio.Address);
        end;

        Data := NewDevice;
      end;

      AServices := Services;

      if Assigned(Services) then
        for Loop := 0 to AServices.Count - 1 do begin
          AService := AServices[Loop];

          if Assigned(AService) then
            with AService, Add do begin
              Caption := '';

              with SubItems do begin
                Add(GUIDToString(UUID));
                Add('0x' + IntToHex(UUID16, 4));
                Add('0x' + IntToHex(Channel, 2));
                Add(Name);
                Add(Comment);
              end;

              Data := nil;
            end;
        end;
    end;
  end;
end;

procedure TfmMain.btBluetoothDiscoveryClick(Sender: TObject);
var
  Devices: TBFBluetoothDevices;
begin
  Devices := BFBluetoothDiscovery.Discovery(SelectBluetoothRadio, cbBluetoothFast.Checked, cbBluetoothNeedServices.Checked);

  if Assigned(Devices) then begin
    ShowBluetoothDevices(Devices);

    Devices.Free;
  end;
end;

procedure TfmMain.btBluetoothNonBlockingDiscoveryClick(Sender: TObject);
begin
  BFBluetoothDiscovery.Discovery(SelectBluetoothRadio, cbBluetoothFast.Checked, cbBluetoothNeedServices.Checked, False);

  lbBluetoothDevices.Items.Add('Non blocking discovery started');
end;

procedure TfmMain.btBluetoothSelectDeviceClick(Sender: TObject);
var
  Device: TBFBluetoothDevice;
  Loop: Integer;
begin
  Device := BFBluetoothDiscovery.SelectDevice(cbBluetoothFast.Checked);

  with lvBluetoothDevices do
    with Items do begin
      BeginUpdate;
      for Loop := 0 to Count - 1 do
        with Items[Loop] do
          if Assigned(Data) then
            TBFBluetoothDevice(Data).Free;

      Clear;

      if Assigned(Device) then begin
        ShowBluetoothDevice(Device);

        Device.Free;
      end;

      EndUpdate;
    end;
end;

procedure TfmMain.btBluetoothStartMonitoringClick(Sender: TObject);
begin
  BFBluetoothDiscovery.StartMonitoring(SelectBluetoothRadio, cbBluetoothAlwaysNew.Checked, cbBluetoothNeedServices.Checked or (baWinSock in BFAPIInfo.BluetoothAPIs));
end;

procedure TfmMain.btBluetoothStopMonitoringClick(Sender: TObject);
begin
  BFBluetoothDiscovery.StopMonitoring;
end;

procedure TfmMain.btBluetoothDeviceRenameClick(Sender: TObject);
var
  Device: TBFBluetoothDevice;
  AName: string;
begin
  Device := SelectBluetoothDevice;

  if Assigned(Device) then 
    if InputQuery('Rename remote device', 'New name', AName) then begin
      Device.Name := AName;

      lvBluetoothDevices.Selected.SubItems[7] := AName;
    end;
end;

procedure TfmMain.btBluetoothUnpairClick(Sender: TObject);
var
  Device: TBFBluetoothDevice;
begin
  Device := SelectBluetoothDevice;

  if Assigned(Device) then
    if MessageDlg('Unpair device?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then begin
      Device.Unpair;

      lvBluetoothDevices.Selected.SubItems[0] := 'False';
    end;
end;

procedure TfmMain.btBluetoothPairClick(Sender: TObject);
var
  Device: TBFBluetoothDevice;
  APIN: string;
begin
  Device := SelectBluetoothDevice;

  if Assigned(Device) then
    if InputQuery('Pair device', 'PIN', APIN) then begin
      Device.Pair(APIN);

      lvBluetoothDevices.Selected.SubItems[0] := 'True';
    end;
end;

function TfmMain.SelectBluetoothDevice: TBFBluetoothDevice;
var
  Selected: TListItem;
begin
  Result := nil;

  Selected := lvBluetoothDevices.Selected;

  if not Assigned(Selected) then
    MessageDlg('Selected device', mtError, [mbOK], 0)

  else begin
    Result := TBFBluetoothDevice(Selected.Data);

    if not Assigned(Result) then MessageDlg('Selected device', mtError, [mbOK], 0);
  end;
end;

procedure TfmMain.btEnumPortsClick(Sender: TObject);
var
  Ports: TBFCOMPorts;
  Port: TBFCOMPort;
  Loop: Integer;
begin
  with lvPorts.Items do begin
    BeginUpdate;
    Clear;

    Ports := BFBluetoothDiscovery.EnumCOMPorts;

    if Assigned(Ports) then begin
      for Loop := 0 to Ports.Count - 1 do begin
        Port := Ports[Loop];

        if Assigned(Port) then
          with Add, Port do begin
            Caption := Name;

            SubItems.Add(IntToStr(Number));
          end;
      end;

      Ports.Free;
    end;
    
    EndUpdate;
  end;
end;

procedure TfmMain.btEnumRadiosClick(Sender: TObject);
var
  Loop: Integer;
  NewRadio: TBFBluetoothRadio;
  Radio: TBFBluetoothRadio;
  Radios: TBFBluetoothRadios;
begin
  with lvRadios do
    with Items do begin
      BeginUpdate;

      for Loop := 0 to Count - 1 do
        with Items[Loop] do
          if Assigned(Data) then
            TBFBluetoothRadio(Data).Free;

      Clear;

      Radios := BFBluetoothDiscovery.EnumRadios;

      if Assigned(Radios) then begin
        for Loop := 0 to Radios.Count - 1 do begin
          Radio := Radios[Loop];

          if Assigned(Radio) then begin
            NewRadio := TBFBluetoothRadio.Create;
            NewRadio.Assign(Radio);

            with NewRadio, Add do begin
              Caption := Address;

              with SubItems do begin
                Add('0x' + IntToHex(BTAddress, 12));
                Add('0x' + IntToHex(ClassOfDevice, 8));
                Add(ClassOfDeviceName);
                try
                  Add(BFBoolToStr(Connectable));
                except
                  Add('Not supported');
                end;
                try
                  Add(BFBoolToStr(Discoverable));
                except
                  Add('Not supported');
                end;
                Add('0x' + IntToHex(Manufacturer, 4));
                Add(Name);
                Add('0x' + IntToHex(Subversion, 4));

                case BluetoothAPI of
                  baBlueSoleil: Add('BlueSoleil');
                  baWinSock: Add('Microsoft');
                  baWidComm: Add('WidComm');
                  baToshiba: Add('Toshiba');
                end;
                
                Add(Version);
              end;

              Data := NewRadio;
            end;
          end;
        end;

        Radios.Free;
      end;

      EndUpdate;
    end;
end;

function TfmMain.SelectBluetoothRadio: TBFBluetoothRadio;
var
  Selected: TListItem;
begin
  Selected := lvRadios.Selected;

  if not Assigned(Selected) then
    Result := nil

  else
    Result := TBFBluetoothRadio(Selected.Data);
end;

procedure TfmMain.btDiscoverableClick(Sender: TObject);
var
  Radio: TBFBluetoothRadio;
begin
  Radio := SelectBluetoothRadio;

  if Assigned(Radio) then
    with lvRadios.Selected do
      case MessageDlg('Set discoverable?', mtConfirmation, [mbYes, mbNo, mbCancel], 0) of
        mrYes: begin
                 Radio.Discoverable := True;
                 SubItems[4] := 'True';
               end;
        mrNo: begin
                Radio.Discoverable := False;
                SubItems[4] := 'False';
              end;
      end;
end;

procedure TfmMain.btConnectableClick(Sender: TObject);
var
  Radio: TBFBluetoothRadio;
begin
  Radio := SelectBluetoothRadio;

  if Assigned(Radio) then
    with lvRadios.Selected do
      case MessageDlg('Set connectable?', mtConfirmation, [mbYes, mbNo, mbCancel], 0) of
        mrYes: begin
                 Radio.Connectable := True;
                 SubItems[3] := 'True';
               end;
        mrNo: begin
                Radio.Connectable := False;
                SubItems[3] := 'False';
              end;
      end;
end;

procedure TfmMain.btRenameRadiosClick(Sender: TObject);
var
  Radio: TBFBluetoothRadio;
  AName: string;
begin
  Radio := SelectBluetoothRadio;

  if Assigned(Radio) then
    if InputQuery('Rename radio', 'New name', AName) then begin
      Radio.Name := AName;
      lvRadios.Selected.SubItems[6] := AName;
    end;
end;

procedure TfmMain.BFIrDADiscoveryComplete(Sender: TObject; Devices: TBFIrDADevices);
begin
  lbIrDA.Items.Add('Non blocking discovery complete. Found: ' + IntToStr(Devices.Count) + ' device(s)');

  ShowIrDADevices(Devices);
end;

procedure TfmMain.btIrDADiscoveryClick(Sender: TObject);
var
  Devices: TBFIrDADevices;
begin
  Devices := BFIrDADiscovery.Discovery;

  if Assigned(Devices) then begin
    ShowIrDADevices(Devices);

    Devices.Free;
  end;
end;

procedure TfmMain.ShowIrDADevice(Device: TBFIrDADevice);
begin
  if Assigned(Device) then
    with Device, lvIrDA.Items do
      with Add do begin
        Caption := Address;

        with SubItems do begin
          Add('0x' + IntToHex(CharSet, 2));
          Add('0x' + IntToHex(Hints1, 2));
          Add('0x' + IntToHex(Hints2, 2));
          Add('0x' + IntToHex(Integer(IrDAAddress), 8));
          Add(Name);
        end;
      end;
end;

procedure TfmMain.ShowIrDADevices(Devices: TBFIrDADevices);
var
  Device: TBFIrDADevice;
  Loop: Integer;
begin
  with lvIrDA do
    with Items do begin
      BeginUpdate;
      Clear;

      if Assigned(Devices) then
        for Loop := 0 to Devices.Count - 1 do begin
          Device := Devices[Loop];

          ShowIrDADevice(Device);
        end;

      EndUpdate;
    end;
end;

procedure TfmMain.btIrDANonBlockingClick(Sender: TObject);
begin
  BFIrDADiscovery.Discovery(False);

  lbIrDA.Items.Add('Non blocking discovery started');
end;

procedure TfmMain.btIrDASelectClick(Sender: TObject);
var
  Device: TBFIrDADevice;
begin
  Device := BFIrDADiscovery.SelectDevice;

  with lvIrDA do
    with Items do begin
      BeginUpdate;
      Clear;

      if Assigned(Device) then begin
        ShowIrDADevice(Device);

        Device.Free;
      end;

      EndUpdate;
    end;
end;

procedure TfmMain.btIrDAStartClick(Sender: TObject);
begin
  BFIrDADiscovery.StartMonitoring(cbBluetoothAlwaysNew.Checked);
end;

procedure TfmMain.btIrDAStopClick(Sender: TObject);
begin
  BFIrDADiscovery.StopMonitoring;
end;

procedure TfmMain.BFIrDADiscoveryDeviceFound(Sender: TObject; Device: TBFIrDADevice);
begin
  with Device do lbIrDA.Items.Add('Device found: ' + Address + ' ' + Name);
end;

procedure TfmMain.BFIrDADiscoveryDeviceLost(Sender: TObject; Device: TBFIrDADevice);
begin
  with Device do lbIrDA.Items.Add('Device lost: ' + Address + ' ' + Name);
end;

procedure TfmMain.BFIrDADiscoveryStartMonitoring(Sender: TObject);
begin
  lbIrDA.Items.Add('Monitoring started');
end;

procedure TfmMain.BFIrDADiscoveryStartSearch(Sender: TObject);
begin
  lbIrDA.Items.Add('Search started');
end;

procedure TfmMain.BFIrDADiscoveryStopMonitoring(Sender: TObject);
begin
  lbIrDA.Items.Add('Monitoring stopped');
end;

procedure TfmMain.BFIrDADiscoveryStopSearch(Sender: TObject);
begin
  lbIrDA.Items.Add('Search stopped');
end;

procedure TfmMain.cbFlashChargeClick(Sender: TObject);
begin
  BFCharge.Flash := cbFlashCharge.Checked;
end;

procedure TfmMain.edChargeFlashLevelChange(Sender: TObject);
begin
  BFCharge.FlashLevel := StrToInt(edChargeFlashLevel.Text);
end;

procedure TfmMain.edChargeFlashIntervalChange(Sender: TObject);
begin
  BFCharge.FlashInterval := StrToInt(edChargeFlashInterval.Text);
end;

procedure TfmMain.edChargeLevelChange(Sender: TObject);
begin
  BFCharge.Level := StrToInt(edChargeLevel.Text);
end;

procedure TfmMain.edSignalLevelChange(Sender: TObject);
begin
  BFSignal.Level := StrToInt(edSignalLevel.Text);
end;

procedure TfmMain.btCreateCOMClick(Sender: TObject);
var
  ADevice: TBFBluetoothDevice;
begin
  ADevice := BFBluetoothDiscovery.SelectDevice(False);

  if Assigned(ADevice) then
    try
      with BFBluetoothCOMPortCreator do begin
        Device := ADevice;
        Open;

        lbCOMPort.Items.Add('COM port created: ' + IntToStr(COMNumber));
      end;

    finally
      ADevice.Free;
    end;
end;

procedure TfmMain.cbDestroyCOMClick(Sender: TObject);
begin
  with BFBluetoothCOMPortCreator do
    if Active then begin
      Close;

      lbCOMPort.Items.Add('COM port destroyed');
    end;
end;

procedure TfmMain.btOpenSerialClick(Sender: TObject);
begin
  BFSerialPortClient.OpenDevice;

  with BFSerialPortClient do
    if Active then begin
      meSerial.Lines.Add('Connected');
      if (Transport = atBluetooth) and (not (baWinSock in BFAPIInfo.BluetoothAPIs)) then meSerial.Lines.Add('Signal level: ' + IntToStr(BluetoothTransport.SignalPower));
    end;
end;

procedure TfmMain.btCloseSerialClick(Sender: TObject);
begin
  with BFSerialPortClient do
    if Active then
      Close;
end;

procedure TfmMain.BFSerialPortClientDisconnect(Sender: TObject);
begin
  meSerial.Lines.Add('Disconnected');
end;

procedure TfmMain.BFSerialPortClientData(Sender: TObject);
var
  Data: TBFByteArray;
  Size: Cardinal;
begin
  Size := 255;
  SetLength(Data, 255);

  BFSerialPortClient.Read(Data, Size);

  with meSerial do begin
    Text := Text + string(Data);

    SelStart := Length(Text);
    SelLength := 0;
  end;

  SetLength(Data, 0);
end;

procedure TfmMain.meSerialKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  Cmd: string;
begin
  if Key = VK_RETURN then begin
    Cmd := meSerial.Lines[meSerial.Lines.Count - 1] + CR;

    BFSerialPortClient.Write(TBFByteArray(Cmd));
  end;
end;

procedure TfmMain.btOpenEventsClick(Sender: TObject);
begin
  BFSerialEventsClient.OpenDevice;

  with BFSerialEventsClient do
    if Active then begin
      meEvents.Lines.Add('Connected');
      if (Transport = atBluetooth) and (not (baWinSock in BFAPIInfo.BluetoothAPIs)) then meEvents.Lines.Add('Signal level: ' + IntToStr(BluetoothTransport.SignalPower));
    end;
end;

procedure TfmMain.btCloseEventsClick(Sender: TObject);
begin
  with BFSerialEventsClient do
    if Active then
      Close;
end;

procedure TfmMain.BFSerialEventsClientDisconnect(Sender: TObject);
begin
  meEvents.Lines.Add('Disconnected');
end;

procedure TfmMain.BFSerialEventsClientEvent(Sender: TObject; EventData: String);
begin
  meEvents.Lines.Add(EventData);
end;

procedure TfmMain.btGSMOpenClick(Sender: TObject);
begin
  with BFGSMModemClient do begin
    OpenDevice;

    if Active then begin
      GSMCharge.Level := BatteryCharge.Percent;
      GSMSignal.Level := Signal;
      laClock.Caption := Clock;
      laIMEI.Caption := IMEI;
      laIMSI.Caption := IMSI;
      laManu.Caption := Manufacturer;
      laModel.Caption := Model;
      laFirmware.Caption := SoftVersion;
      case Encoding of
        se8Bit: cbSMSEncoding.ItemIndex := 1;
        seUnicode: cbSMSEncoding.ItemIndex := 2;
      else
        cbSMSEncoding.ItemIndex := 0;
      end;
    end;
  end;
end;

procedure TfmMain.btGSMCloseClick(Sender: TObject);
begin
  with BFGSMModemClient do
    if Active then
      Close;
end;

procedure TfmMain.BFGSMModemClientDisconnect(Sender: TObject);
begin
  GSMCharge.Level := 0;
  GSMSignal.Level := 0;

  laClock.Caption := '';
  laIMEI.Caption := '';
  laIMSI.Caption := '';
  laManu.Caption := '';
  laModel.Caption := '';
  laFirmware.Caption := '';
end;

procedure TfmMain.btReadSettingsClick(Sender: TObject);
begin
  edSCANumber.Text := BFGSMModemClient.ServiceCenter;
  cbRDMemory.ItemIndex := Integer(fmMain.BFGSMModemClient.PrefferedMemory[mmtReadDelete]) - 1;
  cbWSMemory.ItemIndex := Integer(fmMain.BFGSMModemClient.PrefferedMemory[mmtWriteSend]) - 1;
  cbRecMemory.ItemIndex := Integer(fmMain.BFGSMModemClient.PrefferedMemory[mmtReceive]) - 1;
end;

procedure TfmMain.btWriteSettingsClick(Sender: TObject);
begin
  BFGSMModemClient.ServiceCenter := edSCANumber.Text;

  BFGSMModemClient.PrefferedMemory[mmtReadDelete] := TBFSMSMemory(cbRDMemory.ItemIndex + 1);
  BFGSMModemClient.PrefferedMemory[mmtWriteSend] := TBFSMSMemory(cbWSMemory.ItemIndex + 1);
  BFGSMModemClient.PrefferedMemory[mmtReceive] := TBFSMSMemory(cbRecMemory.ItemIndex + 1);
end;

procedure TfmMain.btReadSMSClick(Sender: TObject);
var
  SMS: TBFSMS;
  SMSes: TBFSMSes;
  NewSMS: TBFSMS;
  Loop: Integer;
begin
  with lvSMS do
    with Items do begin
      BeginUpdate;

      for Loop := 0 to Count - 1 do
        if Assigned(Items[Loop].Data) then
          TBFSMS(Items[Loop].Data).Free;

      Clear;

      try
        SMSes := BFGSMModemClient.ReadSMSes(msAll);

        if Assigned(SMSes) then begin
          for Loop := 0 to SMSes.Count - 1 do begin
            SMS := SMSes[Loop];

            if Assigned(SMS) then begin
              NewSMS := TBFSMS.Create;
              NewSMS.Assign(SMS);

              with Add, SMS do begin
                Caption := IntToStr(Index);

                with SubItems do begin
                  try
                    Add(DateTimeToStr(Date));
                  except
                    Add(' ');
                  end;
                  Add(Phone);
                  Add(ServiceCenter);
                  case Status of
                    msRecUnread: Add('Received unreaded');
                    msRecRead: Add('Received readed');
                    msStoUnsent: Add('Stored unsent');
                    msStoSent: Add('Stored sent');
                  end;
                  case SmsType of
                    mtDeliver: Add('Deliver');
                    mtSubmit: Add('Submit');
                    mtDeliverReport: Add('Report');
                  end;

                  Add(SMS.Text);
                end;

                Data := NewSMS;
              end;
            end;
          end;

          SMSes.Free;
        end;
        
      finally
        EndUpdate;
      end;
    end;
end;

procedure TfmMain.btDeleteSMSClick(Sender: TObject);
var
  Selected: TListItem;
  SMS: TBFSMS;
  Loop: Integer;
begin
  Selected := lvSMS.Selected;

  if not Assigned(Selected) then
    MessageDlg('Select SMS', mtError, [mbOK], 0)

  else begin
    SMS := TBFSMS(Selected.Data);

    if not Assigned(SMS) then
      MessageDlg('Select SMS', mtError, [mbOK], 0)

    else begin
      with SMS do begin
        for Loop := 0 to Nested.Count - 1 do
          BFGSMModemClient.DeleteSMS(Nested[Loop].Index);

        BFGSMModemClient.DeleteSMS(Index);
      end;

      SMS.Free;

      lvSMS.Selected.Delete;
    end;
  end;
end;

procedure TfmMain.BFGSMModemClientNew(Sender: TObject; AType: TBFSMSType; AMemory: TBFSMSMemory; AIndex: Integer);
begin
  ShowMessage('New SMS');
end;

procedure TfmMain.btSendSMSClick(Sender: TObject);
begin
  with BFGSMModemClient do begin
    try
      BeginMassSending;
    except
    end;
    SendSMS(BFGSMModemClient.ServiceCenter, edPhone.Text, meSMS.Text, cbFlash.Checked, cbReport.Checked);
    try
      EndMassSending;
    except
    end;
  end;
end;

procedure TfmMain.btSaveSMSClick(Sender: TObject);
begin
  BFGSMModemClient.SaveSMS(BFGSMModemClient.ServiceCenter, edPhone.Text, meSMS.Text, cbFlash.Checked, cbReport.Checked);
end;

procedure TfmMain.btSendSavedClick(Sender: TObject);
var
  Selected: TListItem;
  SMS: TBFSMS;
begin
  Selected := lvSMS.Selected;

  if not Assigned(Selected) then
    MessageDlg('Select SMS', mtError, [mbOK], 0)

  else begin
    SMS := TBFSMS(Selected.Data);

    if not Assigned(SMS) then
      MessageDlg('Select SMS', mtError, [mbOK], 0)

    else
      with SMS do
        BFGSMModemClient.SendSMS(Index, Phone, cbNeedrepSaved.Checked);
  end;
end;

procedure TfmMain.btOPPAbortClick(Sender: TObject);
begin
  FAbort := True;
end;

procedure TfmMain.btOPPSendFileClick(Sender: TObject);
begin
  with BFObjectPushClient do begin
    OpenDevice;

    if Active then
      with OpenDialog do
        if Execute then begin
          FAbort := False;

          try
            Put(FileName);

          finally
            Close;
          end;
        end;
  end;
end;

procedure TfmMain.BFObjectPushClientProgress(Sender: TObject; AName: String; Index, Count, Position, Size: Integer; var Abort: Boolean);
begin
  pbOPP.Max := Size;
  pbOPP.Position := Position;

  Application.ProcessMessages;

  Abort := FAbort;
end;

procedure TfmMain.BFGSMModemClientDown(Sender: TObject; Key: TBFKey);
begin
  lbKeypadEvents.Items.Add('Key pressed: ' + BFGSMModemClient.KeyToChar(Key));
end;

procedure TfmMain.BFGSMModemClientUp(Sender: TObject; Key: TBFKey);
begin
  lbKeypadEvents.Items.Add('Key released: ' + BFGSMModemClient.KeyToChar(Key));
end;

procedure TfmMain.sbLeftBtClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keySoftKey1, 0, 0);
end;

procedure TfmMain.sbRightBtClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keySoftKey2, 0, 0);
end;

procedure TfmMain.sbUpClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyUpArrow, 0, 0);
end;

procedure TfmMain.sbLeftClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyLeftArrow, 0, 0);
end;

procedure TfmMain.sbRightClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyRightArrow, 0, 0);
end;

procedure TfmMain.sbDownClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyDownArrow, 0, 0);
end;

procedure TfmMain.sbMiddleClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyJoyPress, 0, 0);
end;

procedure TfmMain.snAnswerClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keySend, 0, 0);
end;

procedure TfmMain.snEndClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyEnd, 0, 0);
end;

procedure TfmMain.sb1Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key1, 0, 0);
end;

procedure TfmMain.sb2Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key2, 0, 0);
end;

procedure TfmMain.sb3Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key3, 0, 0);
end;

procedure TfmMain.sb4Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key4, 0, 0);
end;

procedure TfmMain.sb5Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key5, 0, 0);
end;

procedure TfmMain.sb6Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key6, 0, 0);
end;

procedure TfmMain.sb7Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key7, 0, 0);
end;

procedure TfmMain.sb8Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key8, 0, 0);
end;

procedure TfmMain.sb9Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key9, 0, 0);
end;

procedure TfmMain.sb0Click(Sender: TObject);
begin
  BFGSMModemClient.PushKey(key0, 0, 0);
end;

procedure TfmMain.sbAsClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyAsterisk, 0, 0);
end;

procedure TfmMain.sbNumClick(Sender: TObject);
begin
  BFGSMModemClient.PushKey(keyHash, 0, 0);
end;

procedure TfmMain.btGSMPhoneBookReadClick(Sender: TObject);
var
  vCard: TBFvCard;
  vCards: TBFvCards;
  Loop: Integer;
begin
  with lvGSMPhoneBook.Items do begin
    BeginUpdate;
    Clear;

    try
      vCards := BFGSMModemClient.ReadPhonebook;

      if Assigned(vCards) then begin
        for Loop := 0 to vCards.Count - 1 do begin
          vCard := vCards[Loop];

          if Assigned(vCard) then
            with Add, vCard do begin
              Caption := Identification.Name.FamilyName;

              SubItems.Add(TelecomInfo.Phone1.Number);
            end;
        end;

        vCards.Free;
      end;

    finally
      EndUpdate;

      pbPhonebook.Max := 0;
      pbPhonebook.Position := 0;
    end;
  end;
end;

procedure TfmMain.btGetPhoneBookClick(Sender: TObject);
begin
  cbPhoneBooks.ItemIndex := Integer(BFGSMModemClient.Phonebook);
end;

procedure TfmMain.btSetPhoneBookClick(Sender: TObject);
begin
  BFGSMModemClient.Phonebook := TBFPhoneBook(cbPhoneBooks.ItemIndex);
end;

procedure TfmMain.BFFileTransferClientProgress(Sender: TObject; AName: String; Index, Count, Position, Size: Integer; var Abort: Boolean);
begin
  pbFS.Max := Size;
  pbFS.Position := Position;

  Application.ProcessMessages;

  Abort := FAbort;
end;

procedure TfmMain.btFSConnectClick(Sender: TObject);
begin
  BFFileTransferClient.OpenDevice;
end;

procedure TfmMain.btFSDisconnectClick(Sender: TObject);
begin
  BFFileTransferClient.Close;
end;

procedure TfmMain.btFSUploadClick(Sender: TObject);
begin
  with OpenDialog do
    if Execute then begin
      FAbort := False;
      BFFileTransferClient.Put(FileName);
    end;
end;

procedure TfmMain.btFSDownloadClick(Sender: TObject);
var
  Data: TBFByteArray;
  Str: TFileStream;
begin
  if Assigned(lvFileTransfer.Selected) then begin
    SetLength(Data, 0);
    BFFileTransferClient.Get(lvFileTransfer.Selected.Caption, Data);

    with SaveDialog do begin
      FileName := lvFileTransfer.Selected.Caption;
      if Execute then begin
        Str := TFileStream.Create(FileName, fmCreate);

        try
          Str.Write(Pointer(Data)^, Length(Data));
          
        finally
          Str.Free;
        end;
      end;
    end;

    SetLength(Data, 0);
  end;
end;

procedure TfmMain.btFSDirClick(Sender: TObject);
var
  Files: TBFFiles;
  AFile: TBFFile;
  Acc: string;
  Loop: Integer;
begin
  with lvFileTransfer do
    with Items do begin
      BeginUpdate;
      Clear;

      try
        Files := BFFileTransferClient.Dir;

        if Assigned(Files) then
          for Loop := 0 to Files.Count - 1 do begin
            AFile := Files[Loop];

            if Assigned(AFile) then
              with Add, AFile do begin
                Caption := Name;

                with SubItems do begin
                  Add(IntToStr(Size));
                  if Folder then
                    Add('Folder')
                  else
                    Add('File');
                  Add(DateTimeToStr(Modified));
                  Acc := '';
                  if faRead in Access then Acc := Acc + 'R';
                  if faWrite in Access then Acc := Acc + 'W';
                  if faDelete in Access then Acc := Acc + 'D';
                  Add(Acc);
                end;
              end;
          end;

      finally
        EndUpdate;
      end;
    end;
end;

procedure TfmMain.btFSCreateFolderClick(Sender: TObject);
var
  AFolder: string;
begin
  if InputQuery('New folder', 'Name', AFolder) then BFFileTransferClient.SetPath(AFolder, True);
end;

procedure TfmMain.btFSSetPathClick(Sender: TObject);
begin
  if Assigned(lvFileTransfer.Selected) then BFFileTransferClient.SetPath(lvFileTransfer.Selected.Caption, False);
end;

procedure TfmMain.btFSAbortClick(Sender: TObject);
begin
  FAbort := True;
end;

procedure TfmMain.btFSRootClick(Sender: TObject);
begin
  BFFileTransferClient.SetPath('', False);
end;

procedure TfmMain.btFSUpClick(Sender: TObject);
begin
  BFFileTransferClient.SetPath('..', False);
end;

procedure TfmMain.btFSDeleteClick(Sender: TObject);
begin
  if Assigned(lvFileTransfer.Selected) then
    if MessageDlg('Delete file/folder?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
      BFFileTransferClient.Delete(lvFileTransfer.Selected.Caption);
end;

procedure TfmMain.btChatServerListenClick(Sender: TObject);
begin
  BFServer.BluetoothTransport.Radio := SelectBluetoothRadio;
  BFServer.Open;
end;

procedure TfmMain.btChatServerCloseClick(Sender: TObject);
begin
  BFServer.Close;
end;

procedure TfmMain.btChatServerSendClick(Sender: TObject);
begin
  BFServer.Write(TBFByteArray(edChatServerText.Text));
end;

procedure TfmMain.BFServerConnect(Sender: TObject);
begin
  lbChatServer.Items.Add('Connected: ' + BFServer.RemoteAddress);
end;

procedure TfmMain.BFServerDisconnect(Sender: TObject);
begin
  lbChatServer.Items.Add('Disconnected: ' + BFServer.RemoteAddress);
end;

procedure TfmMain.BFServerData(Sender: TObject; Data: TBFByteArray);
begin
  lbChatServer.Items.Add(string(Data) + ' ');
end;

procedure TfmMain.btChatClientOpenClick(Sender: TObject);
begin
  BFClient.OpenDevice;
end;

procedure TfmMain.btChatClientCloseClick(Sender: TObject);
begin
  BFClient.Close;
end;

procedure TfmMain.btChatClientSendClick(Sender: TObject);
begin
  BFClient.Write(TBFByteArray(edChatClientText.Text));
end;

procedure TfmMain.BFClientData(Sender: TObject);
var
  Data: TBFByteArray;
  Size: Cardinal;
begin
  SetLength(Data, 0);
  Size := 255;

  try
    BFClient.Read(Data, Size);

    lbChatClient.Items.Add(string(Data) + ' ');

  finally
    SetLength(Data, 0);
  end;
end;

procedure TfmMain.BFClientDisconnect(Sender: TObject);
begin
  lbChatClient.Items.Add('Disconnected');
end;

procedure TfmMain.btOPPServerListenClick(Sender: TObject);
begin
  try
    BFObjectPushServer.BluetoothTransport.Radio := SelectBluetoothRadio;
    BFObjectPushServer.Open;

    lbOPPServer.Items.Add('Bluetooth listen');
  except
    on E: Exception do lbOPPServer.Items.Add('Bluetooth listen error: ' + E.Message);
  end;

  try
    BFObjectPushServerIrDA.Open;

    lbOPPServer.Items.Add('IrDA listen');
  except
    on E: Exception do lbOPPServer.Items.Add('IrDA listen error: ' + E.Message);
  end;
end;

procedure TfmMain.btOPPServerCloseClick(Sender: TObject);
begin
  BFObjectPushServer.Close;
  BFObjectPushServerIrDA.Close;
end;

procedure TfmMain.BFObjectPushServerConnect(Sender: TObject);
begin
  lbOPPServer.Items.Add('Bluetooth connected: ' + BFObjectPushServer.RemoteAddress);
end;

procedure TfmMain.BFObjectPushServerDisconnect(Sender: TObject);
begin
  lbOPPServer.Items.Add('Bluetooth disconnected: ' + BFObjectPushServer.RemoteAddress);
  pbOBServer.Position := 0;
  pbOBServer.Max := 0;
end;

procedure TfmMain.BFObjectPushServerObject(Sender: TObject; AName: String; AObject: TBFByteArray);
var
  Path: string;
  Stream: TFileStream;
begin
  lbOPPServer.Items.Add('Bluetooth object: ' + AName);

  Path := ExtractFilePath(Application.ExeName) + AName;

  Stream := TFileStream.Create(Path, fmCreate);

  try
    Stream.Write(PChar(AObject)^, Length(AObject));

  finally
    Stream.Free;
  end;
end;

procedure TfmMain.BFObjectPushServerIrDAConnect(Sender: TObject);
begin
  lbOPPServer.Items.Add('IrDA connected: ' + BFObjectPushServerIrDA.RemoteAddress);
end;

procedure TfmMain.BFObjectPushServerIrDADisconnect(Sender: TObject);
begin
  lbOPPServer.Items.Add('IrDA disconnected: ' + BFObjectPushServerIrDA.RemoteAddress);
  pbOBServer.Position := 0;
  pbOBServer.Max := 0;
end;

procedure TfmMain.BFObjectPushServerIrDAObject(Sender: TObject; AName: String; AObject: TBFByteArray);
var
  Path: string;
  Stream: TFileStream;
begin
  lbOPPServer.Items.Add('IrDA object: ' + ANAme);

  Path := ExtractFilePath(Application.ExeName) + AName;

  Stream := TFileStream.Create(Path, fmCreate);

  try
    Stream.Write(PChar(AObject)^, Length(AObject));

  finally
    Stream.Free;
  end;
end;

procedure TfmMain.cbSMSEncodingChange(Sender: TObject);
begin
  case cbSMSEncoding.ItemIndex of
    0: BFGSMModemClient.Encoding := se7Bit;
    1: BFGSMModemClient.Encoding := se8Bit;
  else
    BFGSMModemClient.Encoding := seUnicode;
  end;
end;

procedure TfmMain.btAddRecordClick(Sender: TObject);
begin
  with lvGSMPhoneBook.Items do begin
    BeginUpdate;

    with Add do begin
      Caption := edName.Text;
      SubItems.Add(edNumber.Text);
    end;

    EndUpdate;
  end;
end;

procedure TfmMain.btUpdateRecordClick(Sender: TObject);
var
  Selected: TListItem;
begin
  Selected := lvGSMPhoneBook.Selected;

  if Assigned(Selected) then begin
    Selected.Caption := edName.Text;
    Selected.SubItems[0] := edNumber.Text;

  end else
    MessageDlg('Selected record', mtError, [mbOK], 0);
end;

procedure TfmMain.btWritePhonebookClick(Sender: TObject);
var
  Cards: TBFvCards;
  Card: TBFvCard;
  Loop: Integer;
begin
  Cards := TBFvCards.Create;

  for Loop := 0 to lvGSMPhoneBook.Items.Count - 1 do begin
    Card := TBFvCard.Create;

    Card.Identification.Name.FamilyName := lvGSMPhoneBook.Items[Loop].Caption;
    Card.TelecomInfo.Phone1.Number := lvGSMPhoneBook.Items[Loop].SubItems[0];

    Cards.Add(Card);
  end;

  try
    BFGSMModemClient.WritePhonebook(Cards);

  finally
    Cards.Free;

    pbPhonebook.Max := 0;
    pbPhonebook.Position := 0;
  end;
end;

procedure TfmMain.btDeleteRecordClick(Sender: TObject);
var
  Selected: TListItem;
begin
  Selected := lvGSMPhoneBook.Selected;

  if Assigned(Selected) then
    Selected.Delete

  else
    MessageDlg('Selected record', mtError, [mbOK], 0);
end;

procedure TfmMain.lvGSMPhoneBookDblClick(Sender: TObject);
var
  Selected: TListItem;
begin
  Selected := lvGSMPhoneBook.Selected;

  if Assigned(Selected) then begin
    edName.Text := Selected.Caption;
    edNumber.Text := Selected.SubItems[0];

  end else begin
    edName.Text := '';
    edNumber.Text := '';
  end;
end;

procedure TfmMain.BFGSMModemClientPhonebookProgress(Sender: TObject; AIndex, ATotal: Integer);
begin
  pbPhonebook.Max := ATotal;
  pbPhonebook.Position := AIndex;

  Application.ProcessMessages;
end;

procedure TfmMain.btClearFilesClick(Sender: TObject);
begin
  lbFiles.Clear;
end;

procedure TfmMain.btDeleteFileClick(Sender: TObject);
begin
  if lbFiles.ItemIndex = -1 then
    MessageDlg('Select file first', mtError, [mbOK], 0)

  else
    lbFiles.Items.Delete(lbFiles.ItemIndex);
end;

procedure TfmMain.btAddFileClick(Sender: TObject);
begin
  if OpenDialog.Execute then lbFiles.Items.Add(OpenDialog.FileName);
end;

procedure TfmMain.BFFileTransferClientDisconnect(Sender: TObject);
begin
  lvFileTransfer.Items.Clear;
end;

procedure TfmMain.BFObjectPushClientDisconnect(Sender: TObject);
begin
  with pbOPP do begin
    Max := 100;
    Position := 0;
  end;
end;

procedure TfmMain.btRedetectClick(Sender: TObject);
begin
  BFAPIInfo.Redetect;
  DetectTransports;
  DetectBluetoothAPI;
  cbActiveSyncClick(cbActiveSync);
end;

procedure TfmMain.cbWidCommClick(Sender: TObject);
begin
  DetectBluetoothAPI;
end;

procedure TfmMain.BFObjectPushServerIrDAProgress(Sender: TObject; AName: String; APosition, ASize: Cardinal; var AAbort: Boolean);
begin
  pbOBServer.Max := ASize;
  pbOBServer.Position := APosition;

  Application.ProcessMessages;
end;

procedure TfmMain.cbSendvCardClick(Sender: TObject);
begin
  BFBluetoothMassSender.SendCompanyInfo := cbSendvCard.Checked;
end;

procedure TfmMain.BFBluetoothMassSenderAcceptDevice(Sender: TObject; Device: TBFBluetoothDevice; var Accept: Boolean);
begin
  lbMass.Items.Add('OnAcceptDevice: ' + Device.Address + ' on radio: ' + Device.Radio.Address);

  Accept := True;//(Device.Address = '(00:1A:75:B0:74:77)');

  FDevFileRecords[FDevRecordNdx].Addr := Device.Address;
  FDevFileRecords[FDevRecordNdx].Index := 0;

  Inc(FDevRecordNdx);
end;

procedure TfmMain.BFBluetoothMassSenderDiscoveryComplete(Sender: TObject; Count: Integer);
begin
  lbMass.Items.Add('Discovery complete. Founded: ' + IntToStr(Count) + ' devices');
end;

procedure TfmMain.BFBluetoothMassSenderDiscoveryStarted(Sender: TObject);
begin
  lbMass.Items.Add('OnDiscoveryStarted');
  FDevRecordNdx := 0;
end;

procedure TfmMain.BFBluetoothMassSenderNeedFile(Sender: TObject; Device: TBFBluetoothDevice; var FileName: String; var More: Boolean);
var
  Ndx: Integer;

  function GetDevNdx: Integer;
  var
    Loop: Integer;
  begin
    Result := -1;

    for Loop := 0 to 255 do
      if FDevFileRecords[Loop].Addr = Device.Address then begin
        Result := Loop;
        Break;
      end;
  end;

begin
  lbMass.Items.Add('OnNeedFile for device: ' + Device.Address);
  Ndx := GetDevNdx;

  if Ndx = -1 then begin
    FileName := '';
    More := False;
    lbMass.Items.Add('No records for device: ' + Device.Address);

  end else
    if FDevFileRecords[Ndx].Index < lbFiles.Items.Count then begin
      FileName := lbFiles.Items[FDevFileRecords[Ndx].Index];

      Inc(FDevFileRecords[Ndx].Index);

      More := FDevFileRecords[Ndx].Index < lbFiles.Items.Count;

      lbMass.Items.Add('File ' + FileName + ' found for device: ' + Device.Address + ' more=' + BFBoolToStr(More));

    end else begin
      FileName := '';
      More := False;

      lbMass.Items.Add('No files for device: ' + Device.Address);
    end;
end;

procedure TfmMain.BFBluetoothMassSenderSendComplete(Sender: TObject; Device: TBFBluetoothDevice; Status: TBFMSSendResult);
var
  Str: string;
begin
  Str := 'OnSendComplete for device: ' + Device.Address + ' on radio: ' + Device.Radio.Address;

  case Status of
    srSuccess: Str := Str + ' Status: srSuccess';
    srIgnored: Str := Str + ' Status: srIgnored';
    srDeclined: Str := Str + ' Status: srDeclined';
  end;

  lbMass.Items.Add(Str);
end;

procedure TfmMain.BFBluetoothMassSenderSendFileComplete(Sender: TObject; Device: TBFBluetoothDevice; FileName: String; Status: TBFMSSendResult);
var
  Str: string;
begin
  Str := 'OnSendFileComplete for device: ' + Device.Address + ' file: ' + FileName;

  case Status of
    srSuccess: Str := Str + ' Status: srSuccess';
    srIgnored: Str := Str + ' Status: srIgnored';
    srDeclined: Str := Str + ' Status: srDeclined';
  end;

  lbMass.Items.Add(Str);
end;

procedure TfmMain.BFBluetoothMassSenderSendFileStart(Sender: TObject; Device: TBFBluetoothDevice; FileName: String);
begin
  lbMass.Items.Add('OnSendFileStart for device: ' + Device.Address + ' file: ' + FileName);
end;

procedure TfmMain.BFBluetoothMassSenderSendStart(Sender: TObject; Device: TBFBluetoothDevice);
begin
  lbMass.Items.Add('OnSendStart for device: ' + Device.Address + ' on radio: ' + Device.Radio.Address);
end;

procedure TfmMain.BFBluetoothMassSenderSendvCardComplete(Sender: TObject; Device: TBFBluetoothDevice; Status: TBFMSSendResult);
var
  Str: string;
begin
  Str := 'OnSenderSendvCardComplete for device: ' + Device.Address;

  case Status of
    srSuccess: Str := Str + ' Status: srSuccess';
    srIgnored: Str := Str + ' Status: srIgnored';
    srDeclined: Str := Str + ' Status: srDeclined';
  end;

  lbMass.Items.Add(Str);
end;

procedure TfmMain.BFBluetoothMassSenderSendvCardStart(Sender: TObject; Device: TBFBluetoothDevice);
begin
  lbMass.Items.Add('OnSendStartvCardStart for device: ' + Device.Address);
end;

procedure TfmMain.BFBluetoothMassSenderStarted(Sender: TObject);
begin
  lbMass.Items.Add('OnStarted');
end;

procedure TfmMain.BFBluetoothMassSenderStopped(Sender: TObject);
begin
  lbMass.Items.Add('OnStopped');
end;

procedure TfmMain.btMSStartClick(Sender: TObject);
var
  Radios: TBFBluetoothRadios;
begin
  Radios := BFBluetoothDiscovery.EnumRadios;

  if Assigned(Radios) then begin
    if Radios.Count > 0 then begin
      BFBluetoothMassSender.DiscoveryRadio := Radios[0];
      BFBluetoothMassSender.SendRadio := Radios[0];
    end;

    Radios.Free;
  end;

  BFBluetoothMassSender.Start;
end;

procedure TfmMain.btMSStopClick(Sender: TObject);
begin
  BFBluetoothMassSender.Stop;
  BFBluetoothMassSender.SendRadio := nil;
  BFBluetoothMassSender.DiscoveryRadio := nil;
end;

procedure TfmMain.cbActiveSyncClick(Sender: TObject);
begin
  cbActiveSync.Checked := BFAPIInfo.ActiveSync;
end;

procedure TfmMain.btCloseAudioClick(Sender: TObject);
begin
  BFBluetoothAudio.Close;
end;

procedure TfmMain.btOpenAudioClick(Sender: TObject);
var
  Device: TBFBluetoothDevice;
begin
  Device := BFBluetoothDiscovery.SelectDevice(False);
  if Assigned(Device) then begin
    BFBluetoothAudio.Device := Device;
    Device.Free;

    BFBluetoothAudio.Open;
  end;
end;

procedure TfmMain.btCheckDeviceClick(Sender: TObject);
var
  Device: TBFBluetoothDevice;
begin
  Device := SelectBluetoothDevice;

  if Assigned(Device) then
    if BFBluetoothDiscovery.CheckDevice(Device.Address) then
      ShowMessage('Available')
    else
      ShowMessage('Not available');
end;

end.
