An com port gesendete daten lesen
Hallo alle,
wir verwenden eine SMS Notification software, die Broadcasts und Notifications per sms an alle Beützer versendet. Das funktioniert so: 1) Ein ASP.NET Portal & SQL Datenbank ermöglichen die Eingabe von Benachrichtigungen und Nummern der Empfänger 2) Diese Daten werden von einer SMSServerRuntime in gsm befehle umgewandelt 3) Diese werden an COM1 geschickt, wobei COM1 ein USBModem ist, in dem sich die SIM Karte befindet, die dann letztendlich die SMS versendet. Seitdem wir einen Modemwechsel durchgeführt haben, streikt die Software natürlich und nun ist es an mir, herauszufinden warum. Gleich vorweg, ich arbeite mit dem Hersteller der SMSSoftware zusammen, doch er will/kann mir nicht die Sourcecodes geben, aber er arbeitet schon an einem Patch. Ich dachte mir so als Herausforderung, versuche ich ein Delphi Programm zu schreiebn, dass mir bei der Suche nach dem Fehler bisschen hilft, doch leider bin ich in meinen Überlegungen nicht zu mehr gekommen als: 1) Man könnte einen Port emulieren und auslesen welche Befehle er zu gesendet bekommt. 2) Mann könnte die Befehle direkt von Port/ Software lesen. Ich denke Möglichkeit 1) ist seeehr viel schwerer, deshalb denke ich an 2). Ich weiß ja, welche Befehle das Modem eig. bekommen sollte: at+cpin? +CPIN:READY at+csca=xxx OK at+cmgs="xx",xxx +CMGS:(Index) at+cmsp=xx,xx,xx,xx OK (Command : Response) Das sind die GSM Befehle die ich erwarte. Da ich per Hyperterminal ja die SIM einwandfrei steuern kann und auch sms verschicken kann, denke ich der Fehler liegt genau bei der Schnittstelle Software/COM Anschluss. Hat jemand eine Idee, wie ich die gesendeten Befehle auslesen kann?? Ich habe ja schon Bedenken, da der Anschluss nur von einem Programm gleichzeitig verwendet werden kann, aber vielleicht liege ich ja auch ganz falsch. Bin gespannt, ob jemand eine gute Idee hat. lg |
Re: An com port gesendete daten lesen
Warum schließt du nicht an Stelle des Modems einen anderen Rechner an den bisherigen an und liest so die ankommenden Werte? Ich kenne aber das Protokoll nicht und daher kann ich dir auch nicht sagen, ob du evtl. ankommende Nachrichten beantworten musst (ACK oder sowas). Aber ein Versuch ist es wert :) btw: das COM-Kabel muss natürlich gekreuzt sein!
|
Re: An com port gesendete daten lesen
also vielleicht ist das nicht so klar rausgekommen :)
Die SMS Software unterstützt als Modemlocation nur COM1-5 und ich habe das USB Modem am Anschluss COM1 eingerichtet... also softwaremäßig, damit das ganze läuft. Deshalb ist das alles bisschen komplizierter für mich :) |
Re: An com port gesendete daten lesen
Hä? Ich verstehe wohl immer noch nicht ganz :gruebel: Das hier ist doch der aktuelle Stand:
Code:
Richtig soweit?
+-----------+ COM1
| Rechner B | <------------> GSM-Modem +-----------+ Was spricht gegen sowas?
Code:
Oder folgendes
+-----------+ COM1 +-----------+
| Rechner A | <------------> | Rechner B | +-----------+ +-----------+
Code:
+-----------+ COM1
| Rechner B | <-----+------> GSM-Modem +-----------+ | | +-----------+ +------> | Rechner B | +-----------+ |
Re: An com port gesendete daten lesen
Liste der Anhänge anzeigen (Anzahl: 1)
hmm... okay also vielleicht wirds klarer:
Modem -> USB Slot In windows Settings: Modems -> Advanced Port Settings. Dort in dem drop down menu einfach den 'COM1' ausgewählt. (Siehe Anhang) Deshalb hab ich eigentlich keinen "Hardware COM1" Anschluss, da es ja über usb geht- oder versteh ich da was falsch? |
Re: An com port gesendete daten lesen
Naja, du hast einen virtuellen Comport, der wahrscheinlich direkt an den Mikrocontroller geht der an der SIM-Karte hockt. Das ist ein übliches Vorgehen, weil die meisten Mikrocontroller kein USB haben, aber RS232 - also wird ein Bauteil zwischengeschaltet und ein COM-Port über USB bereitgestellt. (es gibt dabei also keinen "COM-Port-Stecker" sondern nur ein paar Leiterbahnen auf der Platine, die diese serielle Verbindung herstellen)
Mein Ansatz wäre folgender (zugegebenermaßen langweiliger als den COM-Port abfangen): Lies die Doku durch die hoffentlich bei beiden Modems dabei war ;) (oder guck, ob beide Hersteller sowas wie ein SDK haben, oder ein Beispiel um über ihr Modem eine SMS zu versenden) |
Re: An com port gesendete daten lesen
ja, also ich weiß welche Befehle am Modem funktionieren und genau die Befehle von der SMSSoftware sind ja das Problem... deswegen "spannend" den Port auslesen :)
Leider hab ich von dem Anbieter noch keine Infos bekommen, welche Befehle gesendet werden und in welchem Format genau (Pud/Text mode). Da das ganze schnell gelöst werden sollte, dachte ich so könnte das schnell gehen... |
Re: An com port gesendete daten lesen
Du brauchst da nichts selbst zu schreiben, google einfach mal nach 'com port monitor' oder 'serial port monitor'. Es gibt da einige Programme, die Dir den Datenverkehr zeitlich korreliert in beide Richtungen anzeigen (auch für virtuelle Ports), und die Daten trotzdem zur Anwendung durchlassen. Teilweise Shareware, teilweise Freeware.
Gruß Erich |
Re: An com port gesendete daten lesen
ah super danke.. ich habe zwar gegoogelt, aber erst jetzt was gefunden!
Danke sehr... //erledigt :) - Doch nicht! Will da gleich weiterarbeiten: Hab mir ein Com Monitor runtergeladen und sehe jetzt genau was das Programm sendet... ich möchte jetzt einmal selber eines schreiben, dass diese Befehle sendet, genau wie zb Hyperterminal. Dazu hab ich schon mal von S.h.a.r.k das verwendet und bisschen umgeschrieben:
Delphi-Quellcode:
so nun das schicken hab ich per virtual serial port schon überprüft, das funktioniert.
unit com_bridge;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Label1: TLabel; Button3: TButton; Button4: TButton; Edit2: TEdit; Label2: TLabel; Button5: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); private { Private declarations } procedure ConnectToCOMPort(Disconnect: Boolean); function ReadDataFromCom(lange:Integer):string; function WriteDataToCOMPort(Text: String): Boolean; public { Public declarations } end; var Form1: TForm1; //Anschluss ComHandle : THandle; comport:string; implementation {$R *.dfm} procedure TForm1.ConnectToCOMPort(Disconnect: Boolean); var DCB : TDCB; TimeOut : TCommTimeouts; i : Integer; begin { Wenn die Verbindung wieder getrennt werden soll } if (Disconnect) then begin FileClose(ComHandle); ComHandle := 0; exit; end else { Die Verbindung zum COM-Port wird hergestellt - wenn dies nicht funktioniert wird es bis zu zehn Mal probiert } begin COMPort:=Edit1.Text; //Com-Ports beginnen bei Com1, Com2, Com3... i := 0; while (ComHandle <= 0) and (i < 10) do begin ComHandle := CreateFile(pchar(COMPort), GENERIC_READ or GENERIC_WRITE,0, nil, OPEN_EXISTING, 0, 0); inc(i); end; { Einstellungen zum COM-Port zuweisen, wenn die Verbindung aktiv ist } if (ComHandle > 0) then begin DCB.DCBlength := SizeOf(DCB); DCB.ByteSize := 8; DCB.Parity := NoParity; DCB.StopBits := ONESTOPBIT; DCB.BaudRate := 9600; { DCB.Flags := 5123; // Wenn 2 Pins belegt sind DCB.EofChar := #0; DCB.ErrorChar := #0; DCB.EvtChar := #0; DCB.XoffChar := #0; DCB.XoffLim := 0; DCB.XonChar := #0; DCB.XonLim := 0; } SetCommState(ComHandle, DCB); GetCommTimeOuts(ComHandle, TimeOut); TimeOut.ReadIntervalTimeOut := 100; TimeOut.ReadTotalTimeoutMultiplier := 0; TimeOut.ReadTotalTimeoutConstant := 250; TimeOut.WriteTotalTimeoutMultiplier := 0; TimeOut.WriteTotalTimeoutConstant := 200; SetCommTimeouts(ComHandle, TimeOut); end; end; end; function TForm1.WriteDataToCOMPort(Text: String): Boolean; var i,k : integer; str:string; begin { Senden der Daten an den COM-Port - mit Ausgabe ob der Befehl erfolgreich war } i:=FileWrite(ComHandle, Text[1], Length(Text)); ShowMessage(str); if (i <> Length(Text)) then Result := False else Result := True; end; function TForm1.ReadDataFromCom(lange:Integer):string; var n:string; begin FileRead(ComHandle,n,lange); ShowMessage(n); Result:=n; end; procedure TForm1.Button1Click(Sender: TObject); begin Application.Terminate; end; procedure TForm1.Button2Click(Sender: TObject); begin ConnectToComPort(false); end; procedure TForm1.Button3Click(Sender: TObject); begin ConnectToComPort(True); ShowMessage('Disconnected from '+Edit1.Text); end; procedure TForm1.Button4Click(Sender: TObject); begin WriteDataToComPort(Edit2.Text); ShowMessage('Write Data Successfull'); end; procedure TForm1.Button5Click(Sender: TObject); begin ReadDataFromCom(length(Edit2.Text)) end; end. Wenn ich aber in hyperterminal mir das anschaue, sehe ich dass irgendwie ein 'Zeilenumbruch' noch gesendet wird, was ist das für ein Befehl? im monitor siehts so aus: Log # / Zeit / Programm / Befehl / Port / Status / Details ... 16 15:36:28 SMSServer IRP_MJ_READ USBER000 TIMEOUT Length 16: AT+CMGF=0...OK.. 17 15:36:28 SMSServer IRP_MJ_WRITE USBER000 SUCCESS Length 11: AT+CMGF=0... 18 15:36:28 SMSServer IRP_MJ_FLUSH_BUFFERS USBER000 SUCCESS ... also dieser "Success" Befehl, den sollte ich auch iwie schicken können, aber das wichtigste ist nun, wie "lese" ich die Antworten vom Modem?? Mein ReadDataFromCom() geht leider nicht, da kommt ein leerer String, wenn ich 2-10 Zeichen Lesen lasse. Wie sollte das genau gehen? |
Re: An com port gesendete daten lesen
muss ich überhaupt extra die Antworten des Modems abwarten und ausgeben, oder geht das iwie automatisch, also als eine Art "echo"?
Wenn man es extra abfragen muss, wäre eine while schleife dafür geeignet?
Delphi-Quellcode:
ich hab irgendwo gelesen, dass einer diese Wartezeit, bis das Modem antwortet, zwar geschafft hat zu verarbeiten aber dauerhaft CPU auf 100%, was bei mir nicht sein darf, da noch andere Programme laufen müssen.
var input: string;
NumberOfBytesRead : dword; Buffer : array[0..255] of char; begin ReadFile(hCommFile, Buffer, sizeof(Buffer), NumberOfBytesRead, nil); //Buffer -> input? while input <> '' do# begin //irgendetwas end; Oder gibt es ein Event im Sinne von "Nachricht erhalten"? Und noch eine kleine Erklärung von ReadFile() wäre ganz super. ReadFile( (COMPort Handle) , (die Variable die den gelesene String bekommt) , ?? , ?? , (wieso nil?) ); muss ein Array of char oder string verwendet werden als input variable? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz