18-08-2020, Saat: 14:22
(18-08-2020, Saat: 12:10)QuAdR Adlı Kullanıcıdan Alıntı: @pro_imaj
Dikkat ederseniz arkadaşın belirttiği yöntemlerde ( Modbus TCP/IP kompenenti, Siemens Profinet için dll dosyaları, Beckhoff için ADS pas. veya OPC ) hazır olan yapılar üzerine geliştirme yapılmış. Burada yapılan işlemler zaten birileri tarafından geliştirilmiş sistemler üzerinden haberleşme yapmak veya sorgu göndermek. Nasıl haberleşme yapıldığını , protokol yapısını, verimliliği hakkında herhangi bir bilgi edinmeden sadece 3. parti bileşenlerle işlem yapmaktır. Profinet i ele alırsak ISO-TSAP standartı haberleşme kullanır. 102 nolu port ile haberleşir. Sizin dediğiniz gibi "Yani firmalar verdikleri verileri sadece kendi geliştirdikleri sistemlere farklı algoritmalar ile gönderiyorlar." siemens haberleşme detaylarını paylaşmaz ama bu sizin bunu çözemeyeceğiniz anlamına gelmez. Burada biraz tersine mühendislik devreye giriyor. Network tabanlı veya seri bir haberleşme yapan, veya aracı bir programla haberleşen herhangi bir sistemde giden gelen paketleri yakalayıp inceleme ile nasıl haberleştiğini çözebilirsiniz. Örnek kod olarak aşağıda profinet protolünü okuma isteği yapma ve yazma isteği yapma procedure lerini bulabilirsiniz.
FirstStartCommand: array[0..21] of byte = ($03,$00,$00,$16,$11,$E0,$00,$00,$00,$01,$00,$C1,$02,$01,$00,$C2, $02,$01,$01,$C0,$01,$09); StartCommand: array[0..24] of byte = ($03, $00, $00, $19, $02, $f0, $80, $32, $01, $00, $00, $00, $00, $00, $08, $00, $00, $f0, $00, $00, $01, $00, $01, $01, $e0); RCommand: array[1..31] of byte = ($03, $00, $00, $1f, $02, $f0, $80, $32, $01, $00, $00, $04, $00, $00, $0e, $00, $00, $04, $01, $12, $0a, $10,$04,$00,$02,$00,$01,$84,$00,$00,$18); // Area ID S7AreaI = $81; S7AreaQ = $82; S7AreaM = $83; S7AreaDB = $84; S7AreaCT = $1C; S7AreaTM = $1D; // Word Length S7WLBit = $01; S7WLByte = $02; S7WLChar = $03; S7WLWord = $04; S7WLInt = $05; S7WLDWord = $06; S7WLDInt = $07; S7WLReal = $08; S7WLDate = $09; S7WLTOD = $0A; S7WLTime = $0B; S7WLS5Time = $0C; S7WLDT = $0F; S7WLCounter = $1C; S7WLTimer = $1D; // Block type Block_OB = $38; Block_DB = $41; Block_SDB = $42; Block_FC = $43; Block_SFC = $44; Block_FB = $45; Block_SFB = $46; // Sub Block Type SubBlk_OB = $08; SubBlk_DB = $0A; SubBlk_SDB = $0B; SubBlk_FC = $0C; SubBlk_SFC = $0D; SubBlk_FB = $0E; SubBlk_SFB = $0F; // Block languages BlockLangAWL = $01; BlockLangKOP = $02; BlockLangFUP = $03; BlockLangSCL = $04; BlockLangDB = $05; BlockLangGRAPH = $06; //Error Code NoError = 0; // Success WrongCPU_Type = 1; ConnectionError = 2; //IPAdressNotAvailable WrongVarFormat = 10; WrongNumberReceivedBytes = 11; SendData = 20; ReadData = 30; WriteData = 50; InvalidAdress = 5; function TProfinetProtocol.MakeReadRequest(mType: Byte; ReadType:string; BaslangicAdresi, DbNo, Size: integer): integer; var HexStr: string; i: integer; begin // Count := 2; i := 0; Result := 0; //RCommand[0] := $03; RCommand[1] := $00; RCommand[2] := $00; RCommand[3] := $1f; //RCommand[4] := $02; RCommand[5] := $f0; RCommand[6] := $80; // RCommand[7] := $32; RCommand[8] := $01; RCommand[9] := $00; RCommand[7] := $00; HexStr := IntToHex(Count,4); //gönderilen istek sayısı RCommand[12] := HexToInt(copy(HexStr,1,2)); ; RCommand[13] := HexToInt(copy(HexStr,3,2)); // RCommand[12] := $00; RCommand[13] := $0e; // RCommand[14] := $00; RCommand[15] := $00; // RCommand[16] := $04; //RCommand[17] := $01; // RCommand[18] := $12; RCommand[19] := $0a; //RCommand[20] := $10; //Taşıma uzunluğu word - byte - bit // RCommand[23] := $04; HexStr := IntToHex(Size ,4); //Okunacak data sayısı RCommand[24] := HexToInt(copy(HexStr,1,2)); ; RCommand[25] := HexToInt(copy(HexStr,3,2)); //Blok numarası HexStr := IntToHex(DbNo ,4); RCommand[26] := HexToInt(copy(HexStr,1,2)); ; RCommand[27] := HexToInt(copy(HexStr,3,2)); RCommand[28] := mType; if ReadType = 'W' then begin if mType = S7AreaDB then begin i := BaslangicAdresi * 8; i := i * 2; Result := 2 * Size; end; if mType = S7AreaM then begin i := BaslangicAdresi; Result := Size; end; RCommand[23] := S7WLWord; end; if ReadType = 'O' then begin i := BaslangicAdresi * 8; Result := 2 * Size; RCommand[23] := S7WLByte; end; if ReadType = 'B' then begin i := BaslangicAdresi; Result := Size; RCommand[23] := S7WLBit; end; HexStr := IntToHex(i,6); RCommand[29] := HexToInt(copy(HexStr,1,2)); RCommand[30] := HexToInt(copy(HexStr,3,2)); RCommand[31] := HexToInt(copy(HexStr,5,2)); if Count = 32000 then Count := 0 else Count := Count + 1; end; procedure TProfinetProtocol.MakeWriteRequest(mType: Byte; Values, ReadType: string; BaslangicAdresi, DbNo, Size: integer); var DataLength: integer; HexStr: string; Result,i : integer; ValuesList: TStringList; PaketUzunlugu: integer; begin ValuesList := TStringList.Create; ValuesList.CommaText := Values; if ReadType = 'W' then PaketUzunlugu := 35 + (Size * 2); if ReadType = 'O' then PaketUzunlugu := 35 + Size; if ReadType = 'B' then PaketUzunlugu := 35 + Size; SetLength(WriteArray, PaketUzunlugu); WriteArray[0] := $03; WriteArray[1] := $00; HexStr := IntToHex(PaketUzunlugu,4); //paket uzunluğu WriteArray[2] := HexToInt(copy(HexStr,1,2)); WriteArray[3] := HexToInt(copy(HexStr,3,2)); WriteArray[4] := $02; WriteArray[5] := $f0; WriteArray[6] := $80; WriteArray[7] := $32; WriteArray[8] := $01; WriteArray[9] := $00; WriteArray[10] := $00; HexStr := IntToHex(Count,4); //gönderilen istek sayısı WriteArray[11] := HexToInt(copy(HexStr,1,2)); WriteArray[12] := HexToInt(copy(HexStr,3,2)); WriteArray[13] := $00; WriteArray[14] := $0e; //Veri uzunluğu + sabit 4 byte parametre if ReadType = 'W' then begin DataLength := 4 + (2 * Size); HexStr := IntToHex(DataLength,4); WriteArray[15] := HexToInt(copy(HexStr,1,2)); WriteArray[16] := HexToInt(copy(HexStr,3,2)); end; if ReadType = 'O' then begin DataLength := 4 + Size; HexStr := IntToHex(DataLength,4); WriteArray[15] := HexToInt(copy(HexStr,1,2)); WriteArray[16] := HexToInt(copy(HexStr,3,2)); end; if ReadType = 'B' then begin DataLength := 4 + Size; HexStr := IntToHex(DataLength,4); WriteArray[15] := HexToInt(copy(HexStr,1,2)); WriteArray[16] := HexToInt(copy(HexStr,3,2)); end; WriteArray[17] := $05; WriteArray[18] := $01; WriteArray[19] := $12; WriteArray[20] := $0a; WriteArray[21] := $10; HexStr := IntToHex(Size ,4); //Okunacak data sayısı WriteArray[23] := HexToInt(copy(HexStr,1,2)); WriteArray[24] := HexToInt(copy(HexStr,3,2)); //Blok numarası HexStr := IntToHex(DbNo ,4); WriteArray[25] := HexToInt(copy(HexStr,1,2)); WriteArray[26] := HexToInt(copy(HexStr,3,2)); WriteArray[27] := mType; if ReadType = 'W' then begin if mType = S7AreaDB then begin i := BaslangicAdresi * 8; i := i * 2; Result := 2 * Size; Result := 8 * Result; end; if mType = S7AreaM then begin i := BaslangicAdresi; Result := Size; end; WriteArray[22] := S7WLWord; end; if ReadType = 'O' then begin i := BaslangicAdresi * 8; Result := Size * 8; WriteArray[22] := S7WLByte; end; if ReadType = 'B' then begin i := BaslangicAdresi; Result := Size; WriteArray[22] := S7WLBit; end; HexStr := IntToHex(i,6); WriteArray[28] := HexToInt(copy(HexStr,1,2)); WriteArray[29] := HexToInt(copy(HexStr,3,2)); WriteArray[30] := HexToInt(copy(HexStr,5,2)); WriteArray[31] := $00; //Veri tipi word byte... WriteArray[32] := S7WLWord; //WriteArray[22]; if ReadType = 'B' then WriteArray[32] := 3; HexStr := IntToHex(Result, 4); WriteArray[33] := HexToInt(copy(HexStr,1,2)); WriteArray[34] := HexToInt(copy(HexStr,3,2)); for i := 35 to length(WriteArray) - 1 do begin WriteArray[i] := HexToInt(ValuesList[i-35]); end; HexStr := ''; for i := 0 to Length(WriteArray) - 1 do begin HexStr := HexStr + IntToHex(WriteArray[i],2); end; //ShowMessage(HexStr); if Count = 32000 then Count := 0 else Count := Count + 1; end;
Açıklamalarınız için teşekkürler, kafamda eksik kalan yer tamamlanmış oldu, sanırım zaten işin en uğraştırıcı ve zaman alıcı kısmı burası oluşturuyor, buda ayrı bir uzmanlık konusu.
Teşekkürler.

