main.pas

Exported from Notepad++
unit main; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, OleCtrls, SKYPE4COMLib_TLB, StdCtrls, ExtCtrls, setupapi, {MidasLib,} CRTL, Menus, ComCtrls, ImgList, Buttons, Grids, DBGrids, ToolWin, ShellApi, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, IdContext, SHFolder, IniFiles, {stopwatch,} CPort, CPortCtl, LBDSystem, DB, DBClient, DBCtrls, sSkinManager, sPanel, sDBNavigator, acDBGrid, sScrollBox, sPageControl, acAlphaImageList, acProgressBar, sSpeedButton, sGroupBox, sTreeView, sBitBtn, sCheckBox, sListBox, sComboBox, sRadioButton, sButton, sMemo, sSpinEdit, sEdit, sLabel, {sHintManager,} ValEdit, sListView, IdGlobal; type Tfrm_main = class(TForm) ComPort_Modem: TComPort; ComPort_AI: TComPort; ComDataPacket_RING: TComDataPacket; ComPort_UI: TComPort; ComDataPacket_Number: TComDataPacket; ComDataPacket_320: TComDataPacket; ComDataPacket_End: TComDataPacket; ComDataPacket_Connect: TComDataPacket; ds_gsm2skype: TDataSource; pum_main: TPopupMenu; pum_RefreshSkypeContacts: TMenuItem; Skin: TsSkinManager; Panel_Status: TsPanel; Pages: TsPageControl; Page_Main: TsTabSheet; Page_Routing: TsTabSheet; Page_Log: TsTabSheet; il_24: TsAlphaImageList; sb_skype: TsSpeedButton; il_skype: TsAlphaImageList; il_modem: TsAlphaImageList; sb_modem: TsSpeedButton; ComDataPacket_Signal: TComDataPacket; sb_system: TsSpeedButton; il_system: TsAlphaImageList; Tabs: TsPageControl; Tab_Main: TsTabSheet; Tab_System: TsTabSheet; Tab_Modem: TsTabSheet; chk_useskin: TsCheckBox; chk_autostart: TsCheckBox; chk_startminimized: TsCheckBox; chk_BoostFromModem: TsCheckBox; chk_SmoothFromModem: TsCheckBox; Tab_IncomingGSM: TsTabSheet; cbox_IncomingMode: TsComboBox; cbox_IncomingTransferTo: TsComboBox; Tab_IncomingSMS: TsTabSheet; cbox_IncomingSMSMode: TsComboBox; cbox_IncomingSMSTransferTo: TsComboBox; ComDataPacket_SMSCame: TComDataPacket; ComDataPacket_SMSReceived: TComDataPacket; Tab_Events: TsTabSheet; cbox_EventsMode: TsComboBox; cbox_EventsTransferTo: TsComboBox; Memo_Log: TsMemo; Tab_Admins: TsTabSheet; lbox_Admins: TsListBox; lbox_SkypeUsers: TsListBox; Tab_Restrictions: TsTabSheet; edt_codes: TsEdit; chk_SMSFollowToGSM: TsCheckBox; pnl_minmaxCodes: TsPanel; edt_Max: TsDecimalSpinEdit; edt_Min: TsDecimalSpinEdit; Tab_Safety: TsTabSheet; chk_UsePrefix: TsCheckBox; edt_Prefix: TsEdit; sPanel1: TsPanel; tmr_GetInfoFromModem: TTimer; ComDataPacket_OperatorName: TComDataPacket; cbox_ModemNetworkMode: TsComboBox; RouteTable: TsListView; cbox_RouteTable: TsComboBox; AddRecord1: TMenuItem; DeleteRecord1: TMenuItem; N1: TMenuItem; N2: TMenuItem; sb_SaveAll: TsSpeedButton; Procedure SaveRouteTable; Procedure LoadRouteTable; Procedure SaveListViewToFile(AListView: TsListView; sFileName: string); Procedure LoadListViewToFile(AListView: TsListView; sFileName: string); Function LocateGSM(AListView: TsListView; Number: string) : String; Procedure CancelAllSkypeCalls; Procedure ChangeBusy(Sender: TObject); Procedure InitComPorts; Procedure InServerConnect(AContext: TIdContext); Procedure InServerDisconnect(AContext: TIdContext); Procedure InServerExecute(AContext: TIdContext); Procedure OutServerConnect(AContext: TIdContext); Procedure OutServerDisconnect(AContext: TIdContext); Procedure OutServerExecute(AContext: TIdContext); Procedure SpkServerConnect(AContext: TIdContext); Procedure SpkServerDisconnect(AContext: TIdContext); Procedure SpkServerExecute(AContext: TIdContext); Procedure SkypeCallStatus(Sender: TObject; const pCall: ICall; Status: TOleEnum); Procedure SkypeMessageStatus(Sender: TObject; const pMessage: IChatMessage; Status: TChatMessageStatus); Procedure SkypeAttachmentStatus(Sender: TObject; Status: TOleEnum); Procedure RefreshSkypeContacts; Procedure Log(S: String); procedure FormCreate(Sender: TObject); procedure InitSockets; Procedure DeleteSockets; procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure ComDataPacket_RINGPacket(Sender: TObject; const Str: string); procedure ComDataPacket_NumberPacket(Sender: TObject; const Str: string); procedure ComDataPacket_320Packet(Sender: TObject; const Str: string); procedure ComDataPacket_EndPacket(Sender: TObject; const Str: string); procedure ComDataPacket_ConnectPacket(Sender: TObject; const Str: string); procedure pum_RefreshSkypeContactsClick(Sender: TObject); procedure pum_SaveTableClick(Sender: TObject); procedure SkinGetMenuExtraLineData(FirstItem: TMenuItem; var SkinSection, Caption: string; var Glyph: TBitmap; var LineVisible: Boolean); procedure sb_skypeClick(Sender: TObject); procedure ComDataPacket_SignalPacket(Sender: TObject; const Str: string); procedure chk_useskinClick(Sender: TObject); procedure cbox_IncomingModeChange(Sender: TObject); procedure cbox_IncomingSMSModeChange(Sender: TObject); procedure ComDataPacket_SMSCamePacket(Sender: TObject; const Str: string); procedure ComDataPacket_SMSReceivedPacket(Sender: TObject; const Str: string); procedure cbox_EventsModeChange(Sender: TObject); procedure lbox_AdminsDragDrop(Sender, Source: TObject; X, Y: Integer); procedure lbox_AdminsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); procedure lbox_SkypeUsersDragDrop(Sender, Source: TObject; X, Y: Integer); procedure lbox_SkypeUsersDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); procedure chk_UsePrefixClick(Sender: TObject); procedure ComPort_UIAfterOpen(Sender: TObject); procedure tmr_GetInfoFromModemTimer(Sender: TObject); procedure ComDataPacket_OperatorNamePacket(Sender: TObject; const Str: string); Function ChangeNetworkMode(I:Integer): String; procedure cbox_ModemNetworkModeChange(Sender: TObject); Procedure LoadIni; Procedure SaveIni; Procedure ReInitModem; procedure pum_SaveAdjustmentsClick(Sender: TObject); Procedure PlaceCalltoSkype(FromGSM, ToSkype : String; Direction : Integer); procedure chk_BoostFromModemClick(Sender: TObject); procedure chk_SmoothFromModemClick(Sender: TObject); Procedure ReInitStreams; procedure Memo_LogChange(Sender: TObject); procedure RouteTableSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); procedure cbox_RouteTableKeyPress(Sender: TObject; var Key: Char); procedure AddRecord1Click(Sender: TObject); procedure DeleteRecord1Click(Sender: TObject); procedure cbox_RouteTableExit(Sender: TObject); procedure sb_SaveAllClick(Sender: TObject); procedure sb_systemClick(Sender: TObject); private Skype: TSkype; MicInServer: TIdTCPServer; MicOutServer: TIdTCPServer; SpeakerServer: TIdTCPServer; OutContext: TIdContext; InContext: TIdContext; SpkContext: TIdContext; Call: ICall; public { Public declarations } end; Type TIntegers = Array of SmallInt; // Тип для работы с байтовыми буферами, как с Integer Const {$include sounds.inc} // Звуки в массивах Const Protocol = 8; // Версия протокола API Скайпа MicInPort = 13754; // Порт микрофонного входа Скайпа MicOutPort = 13755; // Порт микрофонного выхода Скайпа SpeakerPort = 13756; // Порт выхода звука из Скайпа const PortsGUID: TGUID = '{4D36E978-E325-11CE-BFC1-08002BE10318}'; // ports ModemsGUID: TGUID = '{4D36E96D-E325-11CE-BFC1-08002BE10318}'; // modems // Это работает с Е1550 //PortName_Modem = 'HUAWEI Mobile Connect - 3G Modem'; //PortName_AI = 'HUAWEI Mobile Connect - 3G Application Interface'; //PortName_UI = 'HUAWEI Mobile Connect - 3G PC UI Interface'; // Это работает с Е3531ы PortName_Modem = 'Mobile Connect - Modem'; PortName_AI = 'Mobile Connect - Application Interface'; PortName_UI = 'Mobile Connect - PC UI Interface'; Const MaxLenBuff = 65535; // Размер буфера, больше размера, кторый может установить Скайп в два раза Const AppName = 'LongBridgeDigital'; // Имя программы LogDirName = 'logs'; // Имя подддиректории логов RouteTableFileName = 'routetable.dat'; // Имя файла таблицы роутинга IniFileName = AppName + '.ini'; // Имя INI файла Const IVRCode = '@IVR'; Var AppDirectory : String = ''; // Путь до директории программы, с '\', определяется после запуска AppLogDirectory : String = ''; // Полный путь до директории логов, с обратным слешем, определяется после запуска Const WaitAfterSent = 20; // Ожидание в мс после отправки в модем var frm_main: Tfrm_main; Port_Modem, Port_AI, Port_UI: String; ResampledToModem: TMemoryStream; // Стрим, в который пишутся данные после ресемплинга из 16000 в 80000 RAWDataFromModem: TMemoryStream; // Сырые данные от модема PacketSize: Integer; // Размер пакета, который установил Скайп BuffSpk: TidBytes; // Буфер голоса для чтения из спикеров BuffMic: TidBytes; // Буфер голоса в микрофонный вход скайпа BuffSize: Integer; // Размер буфера глобальный BuffMicSize : Integer; // Размер буфера от микрофона BuffSpkSize : Integer; // Размер буфера от спикеров скайпа SkypeToModemBuff: Array [0 .. MaxLenBuff] of Byte; ModemToSkypeBuff: Array [0 .. MaxLenBuff] of Byte; tomodem: Array [0 .. 319] of Byte; // Массив для отправки в модем frommodem: Array [0 .. 319] of Byte; // Массив для приема из модема FromModemVolumeUp: Boolean = True; // Усиление звука от модема FromModemSmooth: Boolean = True; // Сглаживание звука от модема LBDSystem: TLBDSystem; // LongBridgeDigital главный объект MySkypeName : String; implementation {$R *.dfm} {$INCLUDE routines.inc} // Функции и процедуры, которые не относятся к форме Procedure Tfrm_main.SaveListViewToFile(AListView: TsListView; sFileName: string); Var S: string; SP: TStringList; I, J: integer; begin if AListView.Items.Count>0 then begin sp:=TStringList.Create; for i:=0 to AListView.Items.Count-1 do begin s:=AListView.Items[i].Caption; for j:=0 to AListView.Items[i].SubItems.Count-1 do s:=s+'|'+AListView.Items[i].SubItems[j]; sp.Add(s) end; sp.SaveToFile(sFileName); sp.Free; end; end; Procedure Tfrm_main.LoadListViewToFile(AListView: TsListView; sFileName: string); Var S:string; SP: TStringList; I: integer; begin if fileexists(sFileName) then Begin Sp:=TStringList.Create; sp.LoadFromFile(sFileName); if sp.Count>0 then begin AListView.Clear; for i:=0 to sp.Count-1 do begin s:=sp.Strings[i]; AListView.Items.Add.Caption:=copy(s,1,pos('|',s)-1); delete(s,1,pos('|',s)); while pos('|',s)<>0 do begin AListView.Items[AListView.Items.Count-1].SubItems.add(copy(s,1,pos('|',s)-1)); delete(s,1,pos('|',s)); end; AListView.Items[AListView.Items.Count-1].SubItems.add(s); end; end; sp.Free; end; end; Function GetFileNameFromDateTime(DT: TDateTime) : String; var da : Array[0..6] of Word; x : Integer; Y, M, D, H, Mn, S, mS : Word; Str : String; begin DecodeDate(DT, Y, M ,D); DecodeTime(Now, H, Mn, S, mS); da[0] := Y; da[1] := M; da[2] := D; da[3] := H; da[4] := Mn; da[5] := S; Str := ''; for x := 0 to 4 do if da[x] < 9 then Str := Str + '0' + IntToStr(da[x]) + '-' else Str := Str + IntToStr(da[x]) + '-'; if da[5] < 9 then Str := Str + '0' + IntToStr(da[5]) else Str := Str + IntToStr(da[5]); Result := Str + '.log'; end; Procedure Tfrm_main.ReInitStreams; var x : Integer; begin ResampledToModem.Clear; RAWDataFromModem.Clear; for x := 0 to Length(SkypeToModemBuff) do SkypeToModemBuff[x] := 0; for x := 0 to Length(ModemToSkypeBuff) do ModemToSkypeBuff[x] := 0; end; Function Tfrm_main.ChangeNetworkMode(I:Integer): String; begin case I of 0 : Result := 'AT^SYSCFG=13,1,3fffffff,0,0' + #13; // 2G Only 1 : Result := 'AT^SYSCFG=2,1,3fffffff,0,0' + #13; // 2G Preffered 2 : Result := 'AT^SYSCFG=14,2,3fffffff,0,1' + #13; // 3G Only 3 : Result := 'AT^SYSCFG=2,2,3fffffff,0,1' + #13; // 3G Preffered 4 : Result := 'AT^SYSCFG=2,2,3fffff ff,0,2' + #13; // Both 2G and 3G end; end; Procedure Tfrm_main.SaveRouteTable; begin //cds_gsm2skype.SaveToFile(AppDirectory + RouteTableFileName); // Сохраняем в МОИ ДОКУМЕНТЫ\Имя программы SaveListViewToFile(RouteTable, AppDirectory + RouteTableFileName); end; Procedure Tfrm_main.LoadRouteTable; begin LoadListViewToFile(RouteTable, AppDirectory + RouteTableFileName); end; Function Tfrm_main.LocateGSM(AListView: TsListView; Number: string) : String; var x : Integer; begin Result := ''; if AListView.Items.Count > 0 then // Если записи есть for x := 0 to AListView.Items.Count - 1 do // Начинаем искать по всем if Number = AListView.Items.Item[x].Caption then // Если найдена запись Result := AListView.Items.Item[x].SubItems[0] // Выводим субитем в результат end; procedure Tfrm_main.sb_SaveAllClick(Sender: TObject); begin SaveRouteTable; SaveIni; end; procedure Tfrm_main.sb_skypeClick(Sender: TObject); begin if Skype.AttachmentStatus = apiAttachSuccess then RefreshSkypeContacts; end; procedure Tfrm_main.sb_systemClick(Sender: TObject); begin if LBDSystem.Busy then LBDSystem.Busy := False; end; procedure Tfrm_main.AddRecord1Click(Sender: TObject); var Item: TListItem; begin Item := TListItem.Create(RouteTable.Items); // инициализируешь новую строку Item.Caption := '+xxxyyzzzz'; // заполнаяешь Item.SubItems.Add('echo123'); // можно проделать в цикле RouteTable.Items.Insert(0); // добавляешь пустую сроку наверх RouteTable.Items.Item[0] := Item; // и вписываешь в нее свою Item.Free; // освобождаешь строку end; Procedure Tfrm_main.CancelAllSkypeCalls; var x: Integer; begin if Skype.ActiveCalls.Count > 0 then for X := 1 to Skype.ActiveCalls.Count do TRY Skype.ActiveCalls[x].Finish; EXCEPT //nothing END; end; Procedure Tfrm_main.RefreshSkypeContacts; var x: Integer; SkypeUsers : TStringList; begin SkypeUsers := TStringList.Create; TRY if Skype.AttachmentStatus = apiAttachSuccess then for x := 1 to Skype.Friends.Count do if not Skype.Friends.Item[x].IsSkypeOutContact then SkypeUsers.Add(Skype.Friends.Item[x].Handle); EXCEPT on E : Exception do Log(E.ClassName + ' ' + E.Message); END; SkypeUsers.Sort; cbox_IncomingTransferTo.Items.Assign(SkypeUsers); cbox_IncomingTransferTo.Items.Insert(0, IVRCode); // Добавляем IVR в начало cbox_RouteTable.Items.Assign(cbox_IncomingTransferTo.Items); // Берем уже с IVR cbox_IncomingSMSTransferTo.Items.Assign((SkypeUsers)); cbox_EventsTransferTo.Items.Assign((SkypeUsers)); lbox_SkypeUsers.Items.Assign(SkypeUsers); SkypeUsers.Free; end; procedure Tfrm_main.cbox_EventsModeChange(Sender: TObject); begin case cbox_EventsMode.ItemIndex of 0..1 : cbox_EventsTransferTo.Enabled := False; 2..3 : cbox_EventsTransferTo.Enabled := True; end; end; procedure Tfrm_main.cbox_IncomingModeChange(Sender: TObject); begin { Режимы реагирования на входящие звонки: 0 - Игнорировать все звонки 1 - Перенаправлять, если адресат есть в таблице роутинга 2 - Перенаправлять, если адресат есть в таблице роутинга, если в таблице нет - переадресовывать на указанный Скайп аккаунт 3 - Переадресовывать все на указанный Скайп аккаунт } case cbox_IncomingMode.ItemIndex of 0..1 : cbox_IncomingTransferTo.Enabled := False; 2..3 : cbox_IncomingTransferTo.Enabled := True; end; end; procedure Tfrm_main.cbox_IncomingSMSModeChange(Sender: TObject); begin { Режимы реагирования на входящие СМС: 0 - Игнорировать все сообщения 1 - Перенаправлять, если адресат есть в таблице роутинга 2 - Перенаправлять, если адресат есть в таблице роутинга и так же отправлять на указанный Скайп аккаунт 3 - Перенаправлять все только на определенный Скайп - аккаунт Все входящие СМС после обработки процедурой стираются. } case cbox_IncomingSMSMode.ItemIndex of 0..1 : cbox_IncomingSMSTransferTo.Enabled := False; 2..3 : cbox_IncomingSMSTransferTo.Enabled := True; end; end; procedure Tfrm_main.cbox_ModemNetworkModeChange(Sender: TObject); begin if ComPort_UI.Connected then ComPort_UI.WriteStr(ChangeNetworkMode(cbox_ModemNetworkMode.ItemIndex)); end; procedure Tfrm_main.cbox_RouteTableExit(Sender: TObject); begin cbox_RouteTable.Visible := False; end; procedure Tfrm_main.cbox_RouteTableKeyPress(Sender: TObject; var Key: Char); begin case Key of Char(VK_RETURN) : begin if RouteTable.ItemIndex >= 0 then RouteTable.Selected.SubItems[0] := cbox_RouteTable.Text; cbox_RouteTable.Visible := False; end; Char(VK_ESCAPE) : cbox_RouteTable.Visible := False; end; end; procedure Tfrm_main.chk_useskinClick(Sender: TObject); begin Skin.Active := chk_useskin.Checked; end; procedure Tfrm_main.chk_BoostFromModemClick(Sender: TObject); begin FromModemVolumeUp := chk_BoostFromModem.Checked; end; procedure Tfrm_main.chk_SmoothFromModemClick(Sender: TObject); begin FromModemSmooth := chk_BoostFromModem.Checked; end; procedure Tfrm_main.chk_UsePrefixClick(Sender: TObject); begin edt_Prefix.Enabled := chk_UsePrefix.Checked; end; Procedure Tfrm_main.PlaceCalltoSkype(FromGSM: string; ToSkype: string; Direction : Integer); begin Log('Direct.' + IntToStr(Direction) + ' call from GSM (' + FromGSM + ') to Skype: ' + ToSkype); TRY //Skype.CurrentUserProfile.FullName := FromGSM; //Sleep(100); Skype.SendMessage(ToSkype, 'Incoming GSM call from: ' + FromGSM); Call := Skype.PlaceCall(ToSkype, '', '', ''); EXCEPT Log('Error when place call to Skype'); LBDSystem.Busy := False; END; end; Procedure Tfrm_main.ChangeBusy(Sender: TObject); var x: Integer; begin case LBDSystem.Busy of True: begin Log('System is busy'); sb_system.ImageIndex := 1; ReInitStreams; // Очищаем все буферы if LBDSystem.Direction = 0 then // LBDSystem.Busy := False; // Сбасываем все входящие if LBDSystem.Direction = 1 then // Ищем ТОЛЬКО в таблице. if LocateGSM(RouteTable, LBDSystem.GSMNumber) <> '' then // Если в таблице есть соответствие if LocateGSM(RouteTable, LBDSystem.GSMNumber) <> IVRCode then // И не IVR PlaceCalltoSkype(LBDSystem.GSMNumber, LocateGSM(RouteTable, LBDSystem.GSMNumber), LBDSystem.Direction) // Звоним туда else LBDSystem.Busy := False // Номер есть, но скайп-аккаунт не заполнен else LBDSystem.Busy := False; // Не найден номер в таблице // Направление #1 if LBDSystem.Direction = 2 then // Ищем в таблице, если нет - смотрим, куда перенаправить if LocateGSM(RouteTable, LBDSystem.GSMNumber) <> '' then // Если в таблице есть номер if LocateGSM(RouteTable, LBDSystem.GSMNumber) <> IVRCode then // И скайп-аккаунт указан PlaceCalltoSkype(LBDSystem.GSMNumber, LocateGSM(RouteTable, LBDSystem.GSMNumber), LBDSystem.Direction) // Звоним туда else LBDSystem.Busy := False // Иначе, если номер в таблице есть, но скайп-аккаунт не указан - сбрасываем все. Не ебите мозги else // В таблице не найден номер, смотрим, указан ли скайп-аккаунт перенаправления звонка if (cbox_IncomingTransferTo.Text <> '') and (cbox_IncomingTransferTo.Text <> IVRCode) then // Если указан и не IVR PlaceCalltoSkype(LBDSystem.GSMNumber, cbox_IncomingTransferTo.Text, LBDSystem.Direction) // Звоним на него else LBDSystem.Busy := False; // Не указан и здесь - сбрасываем // Направление #2 if LBDSystem.Direction = 3 then // Игнорируем таблицу, перенаправляем все входящие на один скайп-аккаунт if (cbox_IncomingTransferTo.Text <> '') and (cbox_IncomingTransferTo.Text <> IVRCode) then // Если скайп-аккаунт указан и не IVR PlaceCalltoSkype(LBDSystem.GSMNumber, cbox_IncomingTransferTo.Text, LBDSystem.Direction) // Звоним туда else LBDSystem.Busy := False; // Иначе сбрасываем // Направление #3 // Направление 11 - юзер, командой DIAL звонит на номер if LBDSystem.Direction = 11 then begin TRY Call := Skype.PlaceCall(LBDSystem.CurrentUser, '', '', ''); EXCEPT Log('Error when place call to Skype'); LBDSystem.Busy := False; END; end; // Направление #11 // Callback по команде администратора if LBDSystem.Direction = 12 then begin TRY Call := Skype.PlaceCall(LBDSystem.CurrentUser, '', '', ''); EXCEPT Log('Error when place call to Skype'); LBDSystem.Busy := False; END; end; // Направление #12 end; // LBDSystem is TRUE False: begin ComPort_UI.WriteStr('AT+CHUP' + #13); CancelAllSkypeCalls; ReInitStreams; ComPort_Modem.ClearBuffer(True, True); ComPort_AI.ClearBuffer(True, True); ComPort_UI.ClearBuffer(True, True); LBDSystem.GSMNumber := ''; LBDSystem.Direction := 0; LBDSystem.BusyBy := ''; Log('System is free'); sb_system.ImageIndex := 0; end; end; end; Procedure Tfrm_main.InitSockets; Begin MicInServer := TIdTCPServer.Create(Self); MicOutServer := TIdTCPServer.Create(Self); SpeakerServer := TIdTCPServer.Create(Self); MicInServer.DefaultPort := MicInPort; MicInServer.OnConnect := InServerConnect; MicInServer.OnDisconnect := InServerDisconnect; MicInServer.OnExecute := InServerExecute; MicOutServer.DefaultPort := MicOutPort; MicOutServer.OnConnect := OutServerConnect; MicOutServer.OnDisconnect := OutServerDisconnect; MicOutServer.OnExecute := OutServerExecute; SpeakerServer.DefaultPort := SpeakerPort; SpeakerServer.OnExecute := SpkServerExecute; SpeakerServer.OnConnect := SpkServerConnect; SpeakerServer.OnDisconnect := SpkServerDisconnect; MicInServer.Active := True; MicOutServer.Active := True; SpeakerServer.Active := True; End; procedure Tfrm_main.DeleteRecord1Click(Sender: TObject); begin if (RouteTable.ItemIndex >= 0) and (RouteTable.Selected.Index = RouteTable.ItemIndex) then RouteTable.Items.Delete(RouteTable.ItemIndex); end; Procedure Tfrm_main.DeleteSockets; begin if MicInServer.Active Then MicInServer.Active := False; if MicOutServer.Active Then MicOutServer.Active := False; if SpeakerServer.Active then SpeakerServer.Active := False; MicInServer.Free; MicOutServer.Free; SpeakerServer.Free; end; Procedure Tfrm_main.InitComPorts; begin ComPort_Modem.Port := Port_Modem; ComPort_Modem.Connected := True; ComPort_AI.Port := Port_AI; ComPort_AI.Connected := True; ComPort_UI.Port := Port_UI; ComPort_UI.Connected := True; // Остальные строки инициализации находятся в методах onAfterOpen end; Procedure Tfrm_main.SkypeAttachmentStatus(Sender: TObject; Status: TOleEnum); Begin if Status = apiAttachAvailable Then Skype.Attach(Protocol, False); Log('Skype attachment status: ' + Skype.Convert.AttachmentStatusToText(Status)); if Status = apiAttachSuccess Then begin MySkypeName := Skype.CurrentUserProfile.FullName; Log('Skype is connected'); RefreshSkypeContacts; end; sb_skype.ImageIndex := Status; End; Procedure Tfrm_main.SkypeCallStatus(Sender: TObject; const pCall: ICall; Status: TOleEnum); Begin Log('Call status: ' + Skype.Convert.CallStatusToText(Status)); if Status = clsRemoteHold then begin Log(LBDSystem.BusyBy + ' paused the conversation'); // BusyBy определился ниже, когда был ответ на звонок ComPort_UI.WriteStr('AT^DDSETEX=0' + #13); // Выключаем звук от модема Sleep(WaitAfterSent); // Немного ждем ReInitStreams; // Очищаем все стримы и буферы ResampledToModem.Write(Sound_Hold, Length(Sound_Hold)); // Загружаем звук из массива в стрим ResampledToModem.Position := 0; // Переводим указатель на начало стрима ComPort_UI.WriteStr('AT^DDSETEX=2' + #13); // Включаем звук на модеме end; if Status = clsInProgress Then Begin TRY if LBDSystem.Direction <> 12 then // Если НЕ! Callmeback - перенаправлять в модем, иначе - звук в скайпе по умолчанию begin Call.InputDevice[callIoDeviceTypeSoundcard] := ''; Call.CaptureMicDevice[callIoDeviceTypePort] := IntToStr(MicInServer.DefaultPort); Call.InputDevice[callIoDeviceTypePort] := IntToStr(MicOutServer.DefaultPort); Call.OutputDevice[callIoDeviceTypeSoundcard] := ''; Call.OutputDevice[callIoDeviceTypePort] := IntToStr(SpeakerServer.DefaultPort); end; LBDSystem.BusyBy := Call.PartnerHandle; // Запоминаем, кто занял систему ReInitStreams; // Освобождаем стримы и буферы case LBDSystem.Direction of 1..3: begin // Направления входящих звонков от GSM стороны Log(LBDSystem.GSMNumber + ' >> ' + LBDSystem.BusyBy); ComPort_UI.WriteStr('ATA' + #13); // Отвечаем на входящий, как только юзер принял Скайп-звонок. end; 11: begin // Направление исходящих звонков со Скайпа на GSM, инициированые командами Скайп-юзера Log(LBDSystem.BusyBy + ' >> ' + LBDSystem.GSMNumber); ComPort_UI.WriteStr('ATD' + LBDSystem.GSMNumber + ';' + #13); // Звоним на GSM Sleep(WaitAfterSent); // Немножко ждем ComPort_UI.WriteStr('AT^DDSETEX=2' + #13); // Включаем звук от модема end; end; EXCEPT Log('Some shit error when Skype inProgress'); END; End; if (Status = clsFinished) or (Status = clsRefused) or (Status = clsBusy) or (Status = clsMissed) or (Status = clsFailed) Then Begin Call := Nil; PacketSize := 0; LBDSystem.Busy := False; // Тушим свет. Сеанс закончился End; End; Procedure Tfrm_main.SkypeMessageStatus(Sender: TObject; const pMessage: IChatMessage; Status: TChatMessageStatus); {$INCLUDE chkcmd.inc} var Answer : String; begin If Status = cmsReceived then begin LBDSystem.CurrentUser := pMessage.FromHandle; Log('Received message from: ' + LBDSystem.CurrentUser + ', Text: ' + pMessage.Body); if CheckCommand(pMessage.Body, Answer, isAdmin(LBDSystem.CurrentUser, lbox_Admins)) > 0 then Skype.SendMessage(LBDSystem.CurrentUser, Answer); end; if Status = cmsSent then Log('Sending message to: ' + pMessage.FromHandle + ', Text: ' + pMessage.Body); end; procedure Tfrm_main.RouteTableSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); var rct : TRect; begin rct := Item.DisplayRect(drSelectBounds); With cbox_RouteTable do begin Visible := False; Text := item.SubItems[0]; Left := rct.Right + 4; Top := rct.Top; Width := RouteTable.Width - rct.Right - 8; Visible := True; end; end; Procedure Tfrm_main.InServerConnect(AContext: TIdContext); Begin Log('In has connected to socket ' + IntToStr(MicInServer.DefaultPort)); InContext := AContext; End; Procedure Tfrm_main.OutServerConnect(AContext: TIdContext); Begin Log('Out has connected to socket ' + IntToStr(MicOutServer.DefaultPort)); OutContext := AContext; End; Procedure Tfrm_main.SpkServerConnect(AContext: TIdContext); Begin Log('Spk has connected to socket ' + IntToStr(SpeakerServer.DefaultPort)); SpkContext := AContext; End; Procedure Tfrm_main.InServerDisconnect(AContext: TIdContext); Begin Log('In has disconnected from socket ' + IntToStr(MicInServer.DefaultPort)); End; Procedure Tfrm_main.OutServerDisconnect(AContext: TIdContext); Begin Log('Out has disconnected from socket ' + IntToStr(MicOutServer.DefaultPort)); End; Procedure Tfrm_main.SpkServerDisconnect(AContext: TIdContext); Begin Log('Spk has disconnected from socket ' + IntToStr(SpeakerServer.DefaultPort)); End; Procedure Tfrm_main.InServerExecute(AContext: TIdContext); Var b1, b2: Integer; Begin if AContext.Connection.IOHandler.InputBufferIsEmpty then AContext.Connection.IOHandler.CheckForDataOnSource(1); if AContext.Connection.IOHandler.InputBufferIsEmpty then Exit; // Reading data from incoming microphone stream. //BuffMicSize := AContext.Connection.IOHandler.RecvBufferSize; //AContext.Connection.IOHandler.ReadBytes(BuffMic, BuffMicSize, False); { if RAWDataFromModem.Size < BuffSize div 2 then begin Sleep(1); Exit; end; } AContext.Connection.IOHandler.ReadBytes(BuffMic, BuffMicSize, False); if Call = Nil Then Exit; //Log('InExecute'); if PacketSize = 0 Then Begin PacketSize := BuffMicSize; Log('Stream packet size: ' + IntToStr(PacketSize) + ' bytes.'); End; // Все, что Модем успел записать в стрим, прочитаем и очистим стрим, пусть пишет сначала RAWDataFromModem.Position := 0; RAWDataFromModem.Read(ModemToSkypeBuff[0], BuffMicSize div 2); //Log('From modem stream - ' + IntToStr(RAWDataFromModem.Size)); RAWDataFromModem.Clear; // Пересемплируем в 16000 Гц b1 := 0; b2 := 0; while b1 <= (BuffMicSize div 2) do begin BuffMic[b2 + 0] := ModemToSkypeBuff[b1 + 0]; BuffMic[b2 + 1] := ModemToSkypeBuff[b1 + 1]; BuffMic[b2 + 2] := ModemToSkypeBuff[b1 + 0]; BuffMic[b2 + 3] := ModemToSkypeBuff[b1 + 1]; b1 := b1 + 2; b2 := b2 + 4; end; // Если сглаживание включено, усредним каждый средний семпл if FromModemSmooth then begin b1 := 0; while b1 <= (BuffMicSize div 2) do begin TIntegers(BuffMic)[b1 + 1] := (TIntegers(BuffMic)[b1] + TIntegers(BuffMic) [b1 + 2]) div 2; b1 := b1 + 2; end; end; // Если усиление включено, усилим каждый семпл в 10 раз if FromModemVolumeUp then For b1 := 0 to (BuffMicSize div 2) do Begin b2 := TIntegers(BuffMic)[b1] * 10; if b2 > 32767 Then b2 := 32767; if b2 < -32768 Then b2 := -32768; TIntegers(BuffMic)[b1] := b2; End; //SetLength(BuffMic, BuffMicSize); // Отправим результат в микрофонный выход Скайпа TRY if OutContext.Connection.Connected Then OutContext.Connection.IOHandler.Write(BuffMic); EXCEPT Log('Out Server is no connected yet!'); END; //Sleep(10); //sw.Stop; //elapsedMiliseconds := sw.ElapsedMiliseconds; End; Procedure Tfrm_main.OutServerExecute(AContext: TIdContext); begin Sleep(10); end; Procedure Tfrm_main.SpkServerExecute(AContext: TIdContext); Var b1, b2: Integer; Begin if AContext.Connection.IOHandler.InputBufferIsEmpty then AContext.Connection.IOHandler.CheckForDataOnSource(1); if AContext.Connection.IOHandler.InputBufferIsEmpty then Exit; { if AContext.Connection.IOHandler.RecvBufferSize < BuffSize then begin Sleep(1); Exit; end; } AContext.Connection.IOHandler.ReadBytes(BuffSpk, BuffSpkSize, False); if Call = Nil Then Exit; //Log('SpkExecute'); // Пересемплируем буфер от Скайпа в буфер Модема и запишем его в стрим b1 := 0; b2 := 0; while b1 <= BuffSpkSize do begin SkypeToModemBuff[b1 + 0] := BuffSpk[b2 + 0]; SkypeToModemBuff[b1 + 1] := BuffSpk[b2 + 1]; b1 := b1 + 2; b2 := b2 + 4; end; ResampledToModem.Clear; ResampledToModem.Write(SkypeToModemBuff[0], BuffSpkSize div 2); //g('To modem stream - ' + IntToStr(ResampledToModem.Size)); ResampledToModem.Position := 0; //sw.Stop; //elapsedMiliseconds := sw.ElapsedMiliseconds; End; procedure Tfrm_main.lbox_AdminsDragDrop(Sender, Source: TObject; X, Y: Integer); begin lbox_Admins.Items.Add(lbox_SkypeUsers.Items[lbox_SkypeUsers.ItemIndex]); DeleteDuplicates(lbox_Admins); end; procedure Tfrm_main.lbox_AdminsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin Accept := (Source = lbox_SkypeUsers) and (lbox_SkypeUsers.ItemIndex >= 0); end; procedure Tfrm_main.lbox_SkypeUsersDragDrop(Sender, Source: TObject; X, Y: Integer); begin lbox_Admins.Items.delete(lbox_Admins.ItemIndex); end; procedure Tfrm_main.lbox_SkypeUsersDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin Accept := (Source = lbox_Admins) and (lbox_Admins.ItemIndex >= 0); end; procedure Tfrm_main.tmr_GetInfoFromModemTimer(Sender: TObject); begin if ComPort_UI.Connected then begin ComPort_UI.WriteStr('AT+COPS=3,0' + #13); // Нахождение имени мобильного оператора, установка формата ComPort_UI.WriteStr('AT+COPS?' + #13); // Нахождение имени мобильного оператораб в ответе +COPS: 0,0,"Operator",0 ComPort_UI.WriteStr('AT+CSQ' + #13); // Запрос силы сигнала tmr_GetInfoFromModem.Enabled := True; end else tmr_GetInfoFromModem.Enabled := False; end; procedure Tfrm_main.SkinGetMenuExtraLineData(FirstItem: TMenuItem; var SkinSection, Caption: string; var Glyph: TBitmap; var LineVisible: Boolean); begin Caption := 'LongBridge.Digital'; end; Function ModemIsPresent: Boolean; function EnumerateUsbCom(fName: String; fGUID: TGUID): String; var GUID: TGUID; PnPHandle: HDevInfo; // handle на базу данных драйверов, раздел ports i: DWORD; DeviceInfoData: SP_DEVINFO_DATA; Err: Integer; RequiredLength: DWORD; DevicePath: string; RegType: DWORD; Name: ansistring; // S: string; // DevPID: Word; // DevVID: Word; RegKey: HKey; begin LoadSetupApi; GUID := fGUID; fName := UpperCase(fName); Result := ''; PnPHandle := SetupDiGetClassDevs(@GUID, nil, 0, DIGCF_PRESENT { or DIGCF_DEVICEINTERFACE } ); if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then // не можем открыть базу raise Exception.Create(SysErrorMessage(GetLastError)); try i := 0; // первый порт DeviceInfoData.cbSize := SizeOf(DeviceInfoData); while SetupDiEnumDeviceInfo(PnPHandle, i, DeviceInfoData) do // получаем последовательно порты, пока они есть. begin DevicePath := ''; Name := ''; // получаем размер строчки HardwareID SetupDiGetDeviceRegistryProperty(PnPHandle, DeviceInfoData, { SPDRP_HARDWAREID } SPDRP_FRIENDLYNAME, RegType, nil, 0, RequiredLength); Err := GetLastError; if Err = ERROR_INSUFFICIENT_BUFFER then // только эта ошибка должна возникнуть - все другое - что-то не так begin if Length(Name) < RequiredLength { div SizeOf(Char) } then // если буфер маленький, то SetLength(Name, RequiredLength { div SizeOf(Char)+ 20 } ); // устанавливаем размер буфера if not SetupDiGetDeviceRegistryProperty(PnPHandle, DeviceInfoData, { SPDRP_HARDWAREID } SPDRP_FRIENDLYNAME, RegType, @Name[1], RequiredLength, RequiredLength) then // получаем HardwareID begin inc(i); // если ошибка, то смотрим следущий порт Continue; end; end else raise Exception.Create(SysErrorMessage(Err)); Name := UpperCase(Name); // чтобы сравнивать строки, переводим все в заглавные буквы if Copy(Name, 1, Length(fName)) = fName then // если первые три символа HardwareID = 'USB' - то это у нас виртуальный порт begin SetLength(DevicePath, 10); // 10 символов на название ком-порта - хватит (максимальный COM999999 [последний символ = #0]) RegKey := SetupDiOpenDevRegKey(PnPHandle, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); // получаем Handle на раздел реестра экземпляра устройства if RegKey = INVALID_HANDLE_VALUE then begin inc(i); // если ошибка - следущий порт Continue; end; try RequiredLength := 10 * SizeOf(Char); if RegQueryValueEx(RegKey, 'PortName', nil, @RegType, @DevicePath[1], @RequiredLength) <> ERROR_SUCCESS then // в PortName записано название порта (например - СОМ5) begin inc(i); Continue; end; DevicePath := Copy(DevicePath, 1, RequiredLength div SizeOf(Char) - 1); TRY // Result := StrToInt(DevicePath); Result := DevicePath; EXCEPT Result := ''; END; // результат функции - количество портов для данного VID&PID finally RegCloseKey(RegKey); // Handle надо закрыть, даже в случае ошибки end; end; inc(i); // следущий порт end; finally SetupDiDestroyDeviceInfoList(PnPHandle); // освобождаем занятую память. end; UnloadSetupApi; end; begin Result := False; Port_Modem := EnumerateUsbCom(PortName_Modem, ModemsGUID); Port_AI := EnumerateUsbCom(PortName_AI, PortsGUID); Port_UI := EnumerateUsbCom(PortName_UI, PortsGUID); if (Port_Modem = '') or (Port_AI = '') or (Port_UI = '') then Result := False else Result := True; end; procedure Tfrm_main.ComDataPacket_320Packet(Sender: TObject; const Str: string); var x: Integer; begin // Если пакет получен, начинаем писать в стрим для передачи в Скайп for x := 0 to 319 do begin frommodem[x] := Byte(Str[x + 1]); end; RAWDataFromModem.Write(frommodem[0], 320); // Читаем по кольцу. Для отправки информационных сообщений в модем, путем копирования в стрим из другого стрима if ResampledToModem.Position >= ResampledToModem.Size then ResampledToModem.Position := 0; // И отправляем из стрима Скайпа в модем ResampledToModem.Read(tomodem[0], 320); ComPort_AI.Write(tomodem, 320); end; procedure Tfrm_main.ComDataPacket_ConnectPacket(Sender: TObject; const Str: string); begin // Связь установлена, разрешаем передавать звук в порт AI case LBDSystem.Direction of 1..3 : ComPort_UI.WriteStr('AT^DDSETEX=2' + #13); end; end; procedure Tfrm_main.ComDataPacket_EndPacket(Sender: TObject; const Str: string); begin // Получена строка ^CEND для первой линии (вторую игнорируем), освобождаем систему LBDSystem.Busy := False; end; procedure Tfrm_main.ComDataPacket_NumberPacket(Sender: TObject; const Str: string); begin // Если система не занята, читаем номер, устанавливаем направление, занимаем систему if not LBDSystem.Busy then begin LBDSystem.GSMNumber := Str; Log('Incoming GSM call from: ' + LBDSystem.GSMNumber); LBDSystem.Direction := cbox_IncomingMode.ItemIndex; LBDSystem.Busy := True; end; end; procedure Tfrm_main.ComDataPacket_OperatorNamePacket(Sender: TObject; const Str: string); begin if StrPart('"','"', Str) <> '' then sb_modem.Caption := ' ' + StrPart('"','"', Str) + ' ' else sb_modem.Caption := '???'; sb_modem.Width := 33 + (Length(sb_modem.Caption) * 6); end; procedure Tfrm_main.ComDataPacket_RINGPacket(Sender: TObject; const Str: string); begin // Получили строку RING, узнаем номер Log('Incoming GSM call'); ComPort_UI.WriteStr('AT+CLIP=1' + #13); end; procedure Tfrm_main.ComDataPacket_SignalPacket(Sender: TObject; const Str: string); var x: Integer; begin // Сила сигнала модема sb_modem.Grayed := False; if StrPart(' ', ',', Str) <> '' then TRY x := StrToInt(StrPart(' ', ',', Str)); sb_modem.Hint := IntToStr(x); x := x div 7; if x <= 4 then sb_modem.ImageIndex := x else sb_modem.Grayed := True; EXCEPT sb_modem.Grayed := True; END; end; procedure Tfrm_main.ComDataPacket_SMSCamePacket(Sender: TObject; const Str: string); begin // Получили строку ^CMTI Log('A SMS is came'); ComPort_UI.WriteStr('AT+CMGF=1' + #13); // Переводим в текстовый режим ComPort_UI.WriteStr('AT+CMGR=0' + #13); // Читаем первое сообщение end; procedure Tfrm_main.ComDataPacket_SMSReceivedPacket(Sender: TObject; const Str: string); var sms_fromwhom, sms_text, sms_towhom : String; begin { +CMGR: "REC READ","+380637890072",,"12/09/30,23:40:12+12" 0415044904350020043E04340438043D00200442043504410442 OK } // Принимаем только одно сообщение, обрабатываем и стираем все. Тут не смс центр нахуй. sms_fromwhom := ''; sms_text := ''; sms_fromwhom := StrPart('","', '",,"', Str); // Узнаем, от кого сообщение sms_text := UCSToAnsi(StrPart('"' + #13#10, #13#10#13#10 + 'OK', Str)); // Вырезаеи м декодируем сообщение // Если не декодируется, значит там чистый инглишь, оставляем, как есть if Length(sms_text) = 0 then sms_text := StrPart('"' + #13#10, #13#10#13#10 + 'OK', Str); Log('Incoming SMS from: ' + sms_fromwhom); Log('Text: ' + sms_text); Log(IntToStr(cbox_IncomingSMSMode.ItemIndex)); // Смотрим, куда отправить сообщение sms_towhom := LocateGSM(RouteTable, sms_fromwhom); case cbox_IncomingSMSMode.ItemIndex of 0 : begin // Не принимаем СМС // Никуда не отправляем end; 1 : begin // Отправляем только, если есть в таблице // Смотрим в таблицу if (sms_towhom <> '') and (sms_towhom <> IVRCode) then begin Log('Sending.1 SMS from (' + sms_fromwhom + ') to Skype: ' + sms_towhom); Skype.SendMessage(sms_towhom, 'Incoming SMS from ' + sms_fromwhom + #10 + sms_text); end; // Если не заполнен Скайп-аккаунт или не найден номер в таблице - выходим end; // Условие #2 2 : begin // Ищем в таблице, если нет - перенаправляем if (sms_towhom <> '') and (sms_towhom <> IVRCode) then begin Log('Sending.2 SMS from (' + sms_fromwhom + ') to Skype: ' + sms_towhom); Skype.SendMessage(sms_towhom, 'Incoming SMS from ' + sms_fromwhom + #10 + sms_text); end else // Нет в таблице или криво заполнено, смотрим, что в перенаправлении if (cbox_IncomingSMSTransferTo.Text <> '') and (cbox_IncomingSMSTransferTo.Text <> IVRCode) then begin Log('Sending.2 SMS from (' + sms_fromwhom + ') to Skype: ' + cbox_IncomingSMSTransferTo.Text); Skype.SendMessage(cbox_IncomingSMSTransferTo.Text, 'Incoming SMS from ' + sms_fromwhom + #10 + sms_text); end; end; // Условие #2 3 : begin // В таблицу не смотрим, перенаправляем if (cbox_IncomingSMSTransferTo.Text <> '') and (cbox_IncomingSMSTransferTo.Text <> IVRCode) then begin Log('Sending.3 SMS from (' + sms_fromwhom + ') to Skype: ' + cbox_IncomingSMSTransferTo.Text); Skype.SendMessage(cbox_IncomingSMSTransferTo.Text, 'Incoming SMS from ' + sms_fromwhom + #10 + sms_text); end; end; // Условие #3 end; // CASE ComPort_UI.WriteStr('AT+CMGD=0,4' + #13); // Стираем все сообщения end; procedure Tfrm_main.ComPort_UIAfterOpen(Sender: TObject); begin ReInitModem; end; Procedure Tfrm_main.ReInitModem; begin ComPort_UI.WriteStr(ChangeNetworkMode(cbox_ModemNetworkMode.ItemIndex)); Sleep(WaitAfterSent); ComPort_UI.WriteStr('AT+CREG=1' + #13); // Разрешение регистрации в сети Sleep(WaitAfterSent); ComPort_UI.WriteStr('AT+CSSN=1,1' + #13); // ХЗ что такое Sleep(WaitAfterSent); ComPort_UI.WriteStr('AT+CMEE=1' + #13); // Индикация сообщений об ошибках Sleep(WaitAfterSent); ComPort_UI.WriteStr('ATE0' + #13); // Отключение эха Sleep(WaitAfterSent); //ComPort_UI.WriteStr('AT^HS=0,0' + #13); // Высокая скорость. ХЗ //ComPort_UI.WriteStr('AT+CFUN=1'); // Полная перезагрузка модема ComPort_UI.WriteStr('AT+CCWA=1' + #13); // Ожидание звонка Sleep(WaitAfterSent); ComPort_UI.WriteStr('AT+CLIP=1' + #13); // Определение номера Sleep(WaitAfterSent); ComPort_UI.WriteStr('AT+CNMI=2,1,2,2,0' + #13); // Отображение входящих СМС (+CMTI: "SM",0) Sleep(WaitAfterSent); ComPort_UI.WriteStr('AT+CPMS="SM","SM","SM"' + #13); // Все сообщения на Сим карте Sleep(WaitAfterSent); //ComPort_UI.WriteStr('AT+CPBS="SM"' + #13); // Телефонная книга на сим карте ComPort_UI.WriteStr('AT+CMGD=0,4' + #13); // Удаляем все СМС tmr_GetInfoFromModem.Enabled := True; end; procedure Tfrm_main.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin DeleteSockets; if ComPort_Modem.Connected then ComPort_Modem.Connected := False; if ComPort_AI.Connected then ComPort_AI.Connected := False; if ComPort_UI.Connected then ComPort_UI.Connected := False; ResampledToModem.Free; RAWDataFromModem.Free; SaveRouteTable; SaveIni; LBDSystem.Free; Memo_Log.Lines.SaveToFile(AppLogDirectory + GetFileNameFromDateTime(Now)); CanClose := True; end; procedure Tfrm_main.FormCreate(Sender: TObject); var x: Integer; begin if not ModemIsPresent then begin ShowMessage('Modem not found'); TerminateProcess(GetCurrentProcess, 0); end else begin // Получаем или создаем свою папку у юзера в каталоге if not DirectoryExists(GetSpecialFolderPath(CSIDL_PERSONAL) + '\' + AppName) then CreateDir(GetSpecialFolderPath(CSIDL_PERSONAL) + '\' + AppName); AppDirectory := GetSpecialFolderPath(CSIDL_PERSONAL) + '\' + AppName + '\'; // Получаем или создаем папку логов у юзера в каталоге if not DirectoryExists(GetSpecialFolderPath(CSIDL_PERSONAL) + '\' + AppName + '\' + LogDirName) then CreateDir(GetSpecialFolderPath(CSIDL_PERSONAL) + '\' + AppName + '\' + LogDirName); AppLogDirectory := GetSpecialFolderPath(CSIDL_PERSONAL) + '\' + AppName + '\' + LogDirName + '\'; LoadIni; LoadRouteTable; Log(Port_Modem + ' : ' + PortName_Modem); Log(Port_AI + ' : ' + PortName_AI); Log(Port_UI + ' : ' + PortName_UI); ResampledToModem := TMemoryStream.Create; RAWDataFromModem := TMemoryStream.Create; InitComPorts; InitSockets; Self.OnCloseQuery := FormCloseQuery; Skype := TSkype.Create(Self); Skype.OnAttachmentStatus := SkypeAttachmentStatus; Skype.OnCallStatus := SkypeCallStatus; Skype.OnMessageStatus := SkypeMessageStatus; Skype.Attach(Protocol, False); LBDSystem := TLBDSystem.Create; // Инициализация нашего класса LBDSystem.Busy := False; LBDSystem.Direction:= 0; LBDSystem.OnAfterChangeBusy := ChangeBusy; end; end; Procedure Tfrm_main.Log(S: String); Begin case cbox_EventsMode.ItemIndex of 0 : begin // Nothing end; 1 : begin // Only write to log Memo_Log.Lines.Add(DateTimeToStr(Now)+ ' ' + S); end; 2: begin // Write to log and send to skype-account Memo_Log.Lines.Add(DateTimeToStr(Now)+ ' ' + S); if cbox_EventsTransferTo.Text <> '' then Skype.SendMessage(cbox_EventsTransferTo.Text, 'Log Event: ' + #10 + DateTimeToStr(Now) + ' ' + S); end; 3 : begin // Only send to skype-account if cbox_EventsTransferTo.Text <> '' then Skype.SendMessage(cbox_EventsTransferTo.Text, 'Log Event: ' + #10 + DateTimeToStr(Now) + ' ' + S); end; end; End; procedure Tfrm_main.Memo_LogChange(Sender: TObject); begin if Memo_Log.Lines.Count >= 500 then begin Memo_Log.Lines.SaveToFile(AppLogDirectory + GetFileNameFromDateTime(Now)); Memo_Log.Clear; end; end; procedure Tfrm_main.pum_RefreshSkypeContactsClick(Sender: TObject); begin RefreshSkypeContacts; end; procedure Tfrm_main.pum_SaveAdjustmentsClick(Sender: TObject); begin SaveIni; end; procedure Tfrm_main.pum_SaveTableClick(Sender: TObject); begin SaveRouteTable; end; Procedure Tfrm_main.SaveIni; var Ini: Tinifile; // создаем переменную типа Tinifile x : Integer; begin Ini:=TiniFile.Create(AppDirectory + IniFileName); Ini.WriteBool ('System', 'Use skin', chk_useskin.Checked); Ini.WriteBool ('System', 'Auto start', chk_autostart.Checked); Ini.WriteBool ('System', 'Minimize on start', chk_startminimized.Checked); Ini.WriteInteger('Modem', 'Network mode', cbox_ModemNetworkMode.ItemIndex); Ini.WriteBool ('Modem', 'Boost audio stream', chk_BoostFromModem.Checked); Ini.WriteBool ('Modem', 'Smooth audio stream', chk_SmoothFromModem.Checked); Ini.WriteInteger('Modem', 'BufferSizeMultiplier', BuffSize div 320); Ini.EraseSection('Admins'); //Ini.WriteInteger('Admins','Count',lbox_Admins.Items.Count-1); if lbox_Admins.Count > 0 then for x:=0 to lbox_Admins.Items.Count-1 do Ini.WriteString ('Admins', lbox_Admins.Items[x], lbox_Admins.Items[x]); Ini.WriteInteger('Incoming GSM', 'Mode', cbox_IncomingMode.ItemIndex); Ini.WriteString ('Incoming GSM', 'Tranfer to', cbox_IncomingTransferTo.Text); Ini.WriteInteger('Incoming SMS', 'Mode', cbox_IncomingSMSMode.ItemIndex); Ini.WriteString ('Incoming SMS', 'Tranfer to', cbox_IncomingSMSTransferTo.Text); Ini.WriteInteger('Events', 'Mode', cbox_EventsMode.ItemIndex); Ini.WriteString ('Events', 'Tranfer to', cbox_EventsTransferTo.Text); Ini.WriteString('Restrictions', 'Codes', edt_codes.Text); Ini.WriteString('Restrictions', 'Min', edt_Min.Text); Ini.WriteString('Restrictions', 'Max', edt_Max.Text); Ini.WriteBool ('Restrictions', 'SMS follows', chk_SMSFollowToGSM.Checked); Ini.WriteBool ('Safety', 'Use prefix', chk_UsePrefix.Checked); Ini.WriteString('Safety', 'Prefix', edt_Prefix.Text); Ini.WriteBool('Safety', 'Prefix enabled', edt_Prefix.Enabled); Ini.Free; end; Procedure Tfrm_main.LoadIni; var Ini: Tinifile; // создаем переменную типа Tinifile begin Ini:=TiniFile.Create(AppDirectory + IniFileName); chk_useskin.Checked := Ini.ReadBool('System', 'Use skin', True); chk_autostart.Checked := Ini.ReadBool('System', 'Auto start', False); chk_startminimized.Checked := Ini.ReadBool('System', 'Minimize on start', False); cbox_ModemNetworkMode.ItemIndex := Ini.ReadInteger('Modem', 'Network mode', 0); chk_BoostFromModem.Checked := Ini.ReadBool('Modem', 'Boost audio stream', True); chk_SmoothFromModem.Checked := Ini.ReadBool('Modem', 'Smooth audio stream', True); FromModemVolumeUp := chk_BoostFromModem.Checked; FromModemSmooth := chk_SmoothFromModem.Checked; BuffSize := GetBufferSizeValue(Ini.ReadInteger('Modem', 'BufferSizeMultiplier', 10)); BuffMicSize := BuffSize; BuffSpkSize := BuffSize; Ini.ReadSection('Admins', lbox_Admins.Items); cbox_IncomingMode.ItemIndex := Ini.ReadInteger('Incoming GSM', 'Mode', 2); cbox_IncomingTransferTo.Text := Ini.ReadString('Incoming GSM', 'Tranfer to', 'echo123'); cbox_IncomingSMSMode.ItemIndex := Ini.ReadInteger('Incoming SMS', 'Mode', 2); cbox_IncomingSMSTransferTo.Text := Ini.ReadString('Incoming SMS', 'Tranfer to', 'echo123'); //cbox_EventsMode.ItemIndex := Ini.ReadInteger('Events', 'Mode', 1); //cbox_EventsTransferTo.Text := Ini.ReadString('Events', 'Tranfer to', ''); edt_codes.Text := Ini.ReadString('Restrictions', 'Codes', ''); edt_Min.Text := Ini.ReadString('Restrictions', 'Min', '3'); edt_Max.Text := Ini.ReadString('Restrictions', 'Max', '15'); chk_SMSFollowToGSM.Checked := Ini.ReadBool('Restrictions', 'SMS follows', False); chk_UsePrefix.Checked := Ini.ReadBool('Safety', 'Use prefix', False); edt_Prefix.Text := Ini.ReadString('Safety', 'Prefix', ''); edt_Prefix.Enabled := Ini.ReadBool('Safety', 'Prefix enabled', False); Ini.Free; // cbox_IncomingMode.Items. end; end.