private static void SetupGsm(object sender, GsmEventArgs e) { //Nur beim Verbinden ausführen if (e == null || e.Type != GsmEventArgs.Telegram.GsmConnection || !e.Message.ToLower().Contains("verbunden")) { return; } System.Threading.Thread.Sleep(2000); //Angstpause //Test, ob Modem antwortet Gsm_Basics.AddAtCommand("AT"); //Sicherstellen, dass die ANfrage in der Antwort wiederholt wird. //Gsm_Basics.AddAtCommand("ATE1"); Gsm_Basics.AddAtCommand("AT^SSET=1"); //Set AT+CMEE =2 to enable extended error text. Gsm_Basics.AddAtCommand("AT+CMEE=2"); //Erzwinge, dass bei Fehlerhaftem SMS-Senden "+CMS ERROR: <err>" ausgegeben wird statt "OK" Gsm_Basics.AddAtCommand("AT^SM20=0,0"); //Benachrichtigung bei SIM-Karten erkannt oder Sim-Slot offen/zu Gsm_Basics.AddAtCommand("AT^SCKS=1"); Gsm_Basics.AddAtCommand("AT^SCKS?"); //EIgene Telefonnumer-Nummer der SIM-Karte auslesen Gsm_Basics.AddAtCommand("AT+CNUM"); //SIM-Karte im Mobilfunknetz registriert? Gsm_Basics.AddAtCommand("AT+CREG=1"); //Name Mobilfunknetz? Gsm_Basics.AddAtCommand("AT+COPS?"); //Signalqualität Gsm_Basics.AddAtCommand("AT+CSQ"); //Nicht getestet: Zeit zwischen setzen und Abfragen notwendig? Gsm_Basics.AddAtCommand("AT+CREG?"); //SMS-Service-Center Adresse Gsm_Basics.AddAtCommand("AT+CSCA?"); //Modemhersteller Gsm_Basics.AddAtCommand("AT+CGMI"); //Textmode Gsm_Basics.AddAtCommand("AT+CMGF=1"); //SendATCommand("AT+CPMS=\"SM\""); //ME, SM, MT //SendATCommand("AT+CPMS=\"MT\",\"MT\",\"MT\""); Gsm_Basics.AddAtCommand("AT+CPMS=\"MT\",\"MT\",\"MT\""); //Sendeempfangsbestätigungen abonieren //Quelle: https://www.codeproject.com/questions/271002/delivery-reports-in-at-commands //Quelle: https://www.smssolutions.net/tutorials/gsm/sendsmsat/ //AT+CSMP=<fo> [, <vp> / <scts> [, <pid> [, <dcs> ]]] // <fo> First Octet: // <vp> Validity-Period: 0 - 143 (vp+1 x 5min), 144 - 167 (12 Hours + ((VP-143) x 30 minutes)), [...] Gsm_Basics.AddAtCommand("AT+CSMP=49,1,0,0"); Gsm_Basics.AddAtCommand("AT+CNMI=2,1,2,2,1"); //möglich AT+CNMI=2,1,2,2,1 ReadGsmMemory(); //Rufumleitung BAUSTELLE: nicht ausreichend getestet // //Gsm_Basics.AddAtCommand("ATD*61*+" + Properties.Settings.Default.RelayIncomingCallsTo + "*11*05#;"); //Antwort ^SCCFC : <reason>, <status> (0: inaktiv, 1: aktiv), <class> [,. Gsm_Basics.AddAtCommand("ATD*61*+" + Properties.Settings.Default.RelayIncomingCallsTo + "*05#;"); System.Threading.Thread.Sleep(4000); //Antwort abwarten - Antwort wird nicht ausgewertet. Gsm_Basics.RaiseGsmEvent(GsmEventArgs.Telegram.GsmSystem, "GSM-Setup wird ausgeführt."); }
/// <summary> /// Wird bei jedem Empfang von Daten durch COM aufgerufen! /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void ParseGsmRecEvent(object sender, GsmEventArgs e) { if (e.Type != GsmEventArgs.Telegram.GsmRec) { return; } string input = e.Message; if (input == null) { return; } if (input == "\r\nOK\r\n") { return; } #region SMS-Verarbeitung //COM-Antwort auf Gesendete SMS: Referenzzuweisung für Empfangsbestätigung if (input.Contains("+CMGS:") || input.Contains("+CMSS:")) // { ParseSmsReference(input); } //Liste der Nachrichten im GSM-Speicher if (input.Contains("+CMGL:")) { //Empfangsbestätigungen lesen ParseStatusReport(input); SmsDeletePending(); //Empfangen neuer Nachrichten ParseSmsMessages(input); SmsDeletePending(); } //Indikator neuen Statusreport empfangen if (input.Contains("+CDSI:")) { /* * Meldung einer neu eingegangenen Nachricht von GSM-Modem * * Neuen Statusreport empfangen: * bei AT+CNMI= [ <mode> ][, <mt> ][, <bm> ][, 2 ][, <bfr> ] * erwartete Antwort: +CDSI: <mem3>, <index> * //*/ ReadGsmMemory(); } //Indikator neue SMS empfangen if (input.Contains("+CMTI:")) { /* * Meldung einer neu eingegangenen Nachricht von GSM-Modem * * Neue SMS emfangen: * bei AT+CNMI= [ <mode> ][, 1 ][, <bm> ][, <ds> ][, <bfr> ] * erwartete Antwort: +CMTI: <mem3>, <index> * //*/ ReadGsmMemory(); } //Fehlermeldung von Modem bei SMS senden oder Empfangen if (input.Contains("+CMS ERROR:")) { Gsm_Basics.RaiseGsmEvent(GsmEventArgs.Telegram.GsmError, "Am GSM-Modem ist ein Fehler beim Senden oder Empfangen einer SMSM aufgetreten", input); } #endregion #region Sprachanruf //+CRING: VOICE if (input.Contains("+CRING: VOICE")) { Email.VoiceCallRing(); } #endregion #region SIM-Status //GSM-Signalqualität if (input.Contains("+CSQ:")) { //+CSQ: <rssi> , <ber> //<rssi> Mögliche Werte: 2 - 9 marginal, 10 - 14 OK, 15 - 19 Good, 20 - 30 Excellent, 99 = kein Signal //<ber> Bit-Error-Rate: 0 bis 7 = Sprachqualität absteigend, 99 = unbekannt Regex rS = new Regex(@"CSQ:\s([0-9]+),([0-9]+)"); Match m = rS.Match(input); if (!int.TryParse(m.Groups[1].Value, out int rawQuality)) { return; } int qualityPercent = 0; if (rawQuality < 99) { qualityPercent = rawQuality * 100 / 31; } while (m.Success) { RaiseGsmSignalQualityEvent(new GsmEventArgs(GsmEventArgs.Telegram.GsmSignal, string.Format("GSM Signalstärke {0:00}%", qualityPercent), qualityPercent)); m = m.NextMatch(); } } //Eigene Rufnummer lesen if (input.Contains("+CNUM:")) { Regex r = new Regex(@"\+CNUM: ""(.+)"",""(.+)"",(.*)"); //SAMBA75 Match m = r.Match(input); //Console.WriteLine(input); while (m.Success) { string name = m.Groups[1].Value; string strPhone = m.Groups[2].Value; Gsm_Basics.RaiseGsmEvent(GsmEventArgs.Telegram.GsmOwnPhone, string.Format("Eigene Nummer: '{0}' {1}", name, strPhone), GsmConverter.StrToPhone(strPhone)); m = m.NextMatch(); } } //BAUSTELLE //Herstellername Modem if (input.Contains("+CGMI:")) { Regex r = new Regex(@"\+CGMI\n(.+)"); Match m = r.Match(input); if (m.Success) { GlobalProperty.ModemManufacturer = m.Groups[1].Value; } } //BAUSTELLE //SMS Service-Center Adresse // +CSCA: "+491710760000",145 //+CSCA: "+491710760000",145 if (input.Contains("+CSCA: ")) { //+CSCA: "+491710760000",145 Regex r = new Regex(@"\+CSCA: ""(.+)"",(\d+)"); Match m = r.Match(input); if (m.Success) { GlobalProperty.NetworkServiceCenterNumber = m.Groups[1].Value; } } //SIM-Schubfach / SIM erkannt if (input.Contains("^SCKS:")) { //Antwort auf 'AT^SCKS?': '^SCKS: <mode>,<SimStatus>' Regex r = new Regex(@"\^SCKS: (\d+),(\d+)"); Match m = r.Match(input); if (m.Success) { if (int.TryParse(m.Groups[2].Value, out int simCardHolderStatus)) { if (simCardHolderStatus == 1) { GlobalProperty.SimHolderDetected = true; } else { GlobalProperty.SimHolderDetected = false; } } } else { //Meldung von Modem nach Ereignis 'Sim-Schublade' r = new Regex(@"\^SCKS: (\d+)"); m = r.Match(input); if (m.Success) { if (int.TryParse(m.Groups[1].Value, out int simCardHolderStatus)) { if (simCardHolderStatus == 1) { GlobalProperty.SimHolderDetected = true; } else { GlobalProperty.SimHolderDetected = false; } } } } } //Registrierung im Mobilfunknetz if (input.Contains("+CREG:")) { Regex r = new Regex(@"\+CREG: (\d),(\d)"); //SAMBA75 Match m = r.Match(input); while (m.Success) { if (int.TryParse(m.Groups[2].Value, out int networkRegStatus)) { switch (networkRegStatus) { case 0: GlobalProperty.NetworkRegistrationStatus = "nicht registriert"; break; case 1: GlobalProperty.NetworkRegistrationStatus = "registriert"; SetupGsm(null, null); break; case 2: GlobalProperty.NetworkRegistrationStatus = "Netzsuche"; break; case 3: GlobalProperty.NetworkRegistrationStatus = "Registrierung abgelehnt"; break; case 5: GlobalProperty.NetworkRegistrationStatus = "Roaming"; break; default: GlobalProperty.NetworkRegistrationStatus = "unbekannt"; break; } } m = m.NextMatch(); } if (input.Contains("+CREG: 0,0")) { Gsm_Basics.RaiseGsmEvent(GsmEventArgs.Telegram.GsmError, "Das GSM-Modem ist nicht im Mobilfunknetz angemeldet."); } } //Anbietername Mobilfunknetz if (input.Contains("+COPS:")) { Regex r = new Regex(@"\+COPS: (\d),(\d),""(.*)"""); //z.B. +COPS: 0,0,"T-Mobile D" Match m = r.Match(input); while (m.Success) { GlobalProperty.NetworkProviderName = m.Groups[3].Value; m = m.NextMatch(); } } #endregion }
/// <summary> /// Trigger für das Event SMS erfolgreich versendet /// </summary> /// <param name="e"></param> static void RaiseGsmSignalQualityEvent(GsmEventArgs e) { GsmSignalQualityEvent?.Invoke(null, e); }
static void HandleGsmEvent(object sender, GsmEventArgs e) { switch (e.Type) { case GsmEventArgs.Telegram.GsmConnection: GlobalProperty.ConnectedToModem = (bool)e.Payload; break; case GsmEventArgs.Telegram.GsmError: Console.ForegroundColor = ConsoleColor.Red; Sql.Log(MelBoxSql.LogTopic.Sms, MelBoxSql.LogPrio.Error, e.Message); break; case GsmEventArgs.Telegram.GsmSystem: Console.ForegroundColor = ConsoleColor.Gray; break; case GsmEventArgs.Telegram.GsmOwnPhone: GlobalProperty.OwnPhone = (ulong)e.Payload; return; //keine erneute Ausgabe in Console case GsmEventArgs.Telegram.GsmSignal: Console.ForegroundColor = ConsoleColor.Yellow; GlobalProperty.GsmSignalQuality = (int)e.Payload; if (GlobalProperty.GsmSignalQuality < 30) { Sql.Log(MelBoxSql.LogTopic.Sms, MelBoxSql.LogPrio.Warning, "Mobilfunksignal schwach: " + GlobalProperty.GsmSignalQuality + "%"); } break; case GsmEventArgs.Telegram.GsmRec: Console.ForegroundColor = ConsoleColor.DarkGreen; break; case GsmEventArgs.Telegram.GsmSent: Console.ForegroundColor = ConsoleColor.DarkYellow; break; case GsmEventArgs.Telegram.SmsRec: Console.ForegroundColor = ConsoleColor.Cyan; if ((ConsoleDisplayBlock & (byte)e.Type) == 0) { Sql.Log(MelBoxSql.LogTopic.Sms, MelBoxSql.LogPrio.Info, "Empfangen: " + e.Message); } break; case GsmEventArgs.Telegram.SmsStatus: Console.ForegroundColor = ConsoleColor.DarkCyan; if ((ConsoleDisplayBlock & (byte)e.Type) == 0) { Sql.Log(MelBoxSql.LogTopic.Sms, MelBoxSql.LogPrio.Info, "Status: " + e.Message); } break; case GsmEventArgs.Telegram.SmsSent: Console.ForegroundColor = ConsoleColor.DarkBlue; if ((ConsoleDisplayBlock & (byte)e.Type) == 0) { Sql.Log(MelBoxSql.LogTopic.Sms, MelBoxSql.LogPrio.Info, "Gesendet: " + e.Message); } break; default: Console.ForegroundColor = ConsoleColor.White; break; } if ((ConsoleDisplayBlock & (byte)e.Type) == 0) { Console.WriteLine(e.Type.ToString() + ":\t" + e.Message); } Console.ForegroundColor = ConsoleColor.Gray; }