How can i capture https respond via fiddlercore? - c#

I have download fiddlercore DEMO,and i try to use it in my application whitch was depends on WPF,then i hava a question that in my application i can't capture https responds resources?
enter image description here
my code just under below:
using Fiddler;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
namespace operateToolWPF.Utils
{
public class MyFiddler
{
static Proxy oSecureEndpoint;
static string sSecureEndpointHostname = "localhost";
static int iSecureEndpointPort = 7777;
public List<Fiddler.Session> oAllSessions { get; set; }
public void DoQuit()
{
if (null != oSecureEndpoint) oSecureEndpoint.Dispose();
Fiddler.FiddlerApplication.Shutdown();
//Thread.Sleep(500);
}
private string CalcResponseSize(Session oS)
{
if (null == oS.oResponse) return String.Empty;
var cBytesOut = 0;
if (null != oS.responseBodyBytes) cBytesOut += oS.responseBodyBytes.Length;
if ((null != oS.oResponse) && (null != oS.oResponse.headers)) cBytesOut +=
oS.oResponse.headers.ByteCount();
return cBytesOut.ToString();
}
public void WriteSessionList(List<Fiddler.Session> oAllSessions)
{
ConsoleColor oldColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Session list contains...");
try
{
Monitor.Enter(oAllSessions);
foreach (Session oS in oAllSessions)
{
Console.Write(String.Format("{0} {1} {2} {3} {4} {5} {6}\n", oS.id, oS.oRequest.headers.HTTPMethod, oS.fullUrl, oS.responseCode, oS.oResponse.MIMEType, (oS.Timers.ClientBeginResponse - oS.Timers.ClientBeginRequest), CalcResponseSize(oS)));
}
}
finally
{
Monitor.Exit(oAllSessions);
}
Console.WriteLine();
Console.ForegroundColor = oldColor;
}
public void DoFiddler()
{
oAllSessions = new List<Fiddler.Session>();
//if (!Fiddler.CertMaker.rootCertExists())
//{
// if (!Fiddler.CertMaker.createRootCert())
// {
// throw new Exception("Unable to create cert for FiddlerCore.");
// }
//}
//if (!Fiddler.CertMaker.rootCertIsTrusted())
//{
// if (!Fiddler.CertMaker.trustRootCert())
// {
// throw new Exception("Unable to install FiddlerCore's cert.");
// }
//}
#region AttachEventListeners
Fiddler.FiddlerApplication.OnNotification += delegate(object sender, NotificationEventArgs oNEA) {
Console.WriteLine("** NotifyUser: " + oNEA.NotifyString);
};
Fiddler.FiddlerApplication.Log.OnLogString += delegate(object sender, LogEventArgs oLEA) {
Console.WriteLine("** LogString: " + oLEA.LogString);
};
Fiddler.FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
{
//Console.WriteLine("Fiddler.FiddlerApplication.BeforeRequest");
oS.bBufferResponse = true;
Monitor.Enter(oAllSessions);
oAllSessions.Add(oS);
//Console.Write(String.Format("{0} {1} {2} {3} {4} {5} {6}\n", oS.id, oS.oRequest.headers.HTTPMethod, oS.fullUrl, oS.responseCode, oS.oResponse.MIMEType, (oS.Timers.ClientBeginResponse - oS.Timers.ClientBeginRequest), CalcResponseSize(oS)));
Monitor.Exit(oAllSessions);
oS["X-AutoAuth"] = "(default)";
if ((oS.oRequest.pipeClient.LocalPort == iSecureEndpointPort) && (oS.hostname == sSecureEndpointHostname))
{
oS.utilCreateResponseAndBypassServer();
oS.oResponse.headers.SetStatus(200, "Ok");
oS.oResponse["Content-Type"] = "text/html; charset=UTF-8";
oS.oResponse["Cache-Control"] = "private, max-age=0";
oS.utilSetResponseBody("<html><body>Request for httpS://" + sSecureEndpointHostname + ":" + iSecureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + oS.oRequest.headers.ToString());
}
};
Fiddler.FiddlerApplication.AfterSessionComplete += delegate(Fiddler.Session oS)
{
//Console.WriteLine("Fiddler.FiddlerApplication.AfterSessionComplete");
//Console.Title = ("Session list contains: " + oAllSessions.Count.ToString() + " sessions");
//DoQuit();
};
// Tell the system console to handle CTRL+C by calling our method that
// gracefully shuts down the FiddlerCore.
//
// Note, this doesn't handle the case where the user closes the window with the close button.
// See http://geekswithblogs.net/mrnat/archive/2004/09/23/11594.aspx for info on that...
//
#endregion AttachEventListeners
string sSAZInfo = "NoSAZ";
#if SAZ_SUPPORT
sSAZInfo = Assembly.GetAssembly(typeof(Ionic.Zip.ZipFile)).FullName;
DNZSAZProvider.fnObtainPwd = () =>
{
Console.WriteLine("Enter the password (or just hit Enter to cancel):");
string sResult = Console.ReadLine();
Console.WriteLine();
return sResult;
};
FiddlerApplication.oSAZProvider = new DNZSAZProvider();
#endif
Console.WriteLine(String.Format("Starting {0} ({1})...", Fiddler.FiddlerApplication.GetVersionString(), sSAZInfo));
Fiddler.CONFIG.IgnoreServerCertErrors = false;
FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true);
FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;
int iPort = 8877;
Fiddler.FiddlerApplication.Startup(iPort, oFCSF);
FiddlerApplication.Log.LogFormat("Created endpoint listening on port {0}", iPort);
FiddlerApplication.Log.LogFormat("Starting with settings: [{0}]", oFCSF);
FiddlerApplication.Log.LogFormat("Gateway: {0}", CONFIG.UpstreamGateway.ToString());
oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, sSecureEndpointHostname);
if (null != oSecureEndpoint)
{
FiddlerApplication.Log.LogFormat("Created secure endpoint listening on port {0}, using a HTTPS certificate for '{1}'", iSecureEndpointPort, sSecureEndpointHostname);
}
}
}
}
who can help me ?Thanks!

i Hope this solve all u vr Problem in this Demo application he has Clearly explained how to track the HTTP and HTTPS request.. For HTTP You can directly listen to the AfterSessionComplete event but for HTTPS you need to install the Fiddler core certificate this
https://weblog.west-wind.com/posts/2014/jul/29/using-fiddlercore-to-capture-http-requests-with-net

Related

No supported bluetooth protocol stack found

I use windows 7 and C#, .net4.6.1 in VS2017. I used bluetooth CSR 4.0 dongle and csr hormony bluetooth stack as the third party Bluetooth drivers..
I followed this to write a hcitool program :
Looking to write Bluetooth 'hcitool' equivelant in Windows
But when I tried to run the program to connect the BLE device. error occurs at this line
var dev = new BluetoothDeviceInfo(_searchAddress);
The error is : No supported bluetooth protocol stack found.
I have double checked and the parameters I pass is right(info + the device address)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using InTheHand.Net.Bluetooth;
using InTheHand.Net;
using InTheHand.Net.Sockets;
using System.Diagnostics;
using System.Net.Sockets;
namespace hcitool
{
partial class Program
{
static bool infoRatherThanName;
static BluetoothAddress _searchAddress;
static int Main(string[] args)
{
if (args.Length < 1) {
Console.WriteLine("Please specify command.");
return 2;
}
var cmd = args[0];
switch (cmd) {
case "name":
infoRatherThanName = false;
break;
case "info":
infoRatherThanName = true;
break;
//-
case "dev":
return ShowRadios();
//case "auth":
// return CauseAuth(GETADDRESS());
default:
throw new NotImplementedException("Command: '" + cmd + "'");
}
if (args.Length < 2) {
Console.WriteLine("Please specify device address.");
return 2;
}
var addrS = args[1];
_searchAddress = BluetoothAddress.Parse(addrS);
//
var dev = new BluetoothDeviceInfo(_searchAddress);
bool isInRange = GetCanConnectTo(dev);
if (isInRange) {
PrintDevice(dev);
} else {
Console.WriteLine("Can't see that device.");
}
//
Console.WriteLine("simple");
return Simple();
//return Fancier();
}
//----
private static int ShowRadios()
{
BluetoothRadio[] list;
try {
list = BluetoothRadio.AllRadios;
} catch (Exception) {
return 1;
}
Debug.Assert(list.Length != 0, "Expect zero radios case to raise an error.");
foreach (var curR in list) {
Console.WriteLine("* {0} '{1}'", curR.LocalAddress, curR.Name);
Console.WriteLine("{0}", curR.SoftwareManufacturer);
Console.WriteLine("{0}", curR.Manufacturer);
Console.WriteLine("{0}", curR.Mode);
}//for
return 0;
}
private static int CauseAuth(BluetoothAddress addr)
{
BluetoothSecurity.PairRequest(addr, null);
return 0;
}
//----
static int Simple()
{
BluetoothDeviceInfo[] devices;
BluetoothDeviceInfo foundDev = null;
var cli = new BluetoothClient();
// Fast: Remembered/Authenticated
devices = cli.DiscoverDevices(255, true, true, false, false);
SimpleCheckDevice(devices, ref foundDev);
if (foundDev == null) {
// Slow: Inquiry
cli.DiscoverDevices(255, false, false, true, false);
SimpleCheckDevice(devices, ref foundDev);
}
//
if (foundDev != null) {
return 0;
} else {
return 1;
}
}
private static void SimpleCheckDevice(IEnumerable<BluetoothDeviceInfo> devices,
ref BluetoothDeviceInfo foundDev)
{
foreach (var cur in devices) {
if (cur.DeviceAddress == _searchAddress) {
foundDev = cur;
PrintDevice(cur);
}
}//for
}
private static void PrintDevice(BluetoothDeviceInfo cur)
{
Console.WriteLine("* Found device: '{0}' ", cur.DeviceName);
if (infoRatherThanName) {
try {
var vs = cur.GetVersions();
Console.WriteLine(vs.Manufacturer);
Console.WriteLine(vs.LmpVersion);
Console.WriteLine(vs.LmpSubversion);
Console.WriteLine(vs.LmpSupportedFeatures);
} catch (Exception ex) {
Console.WriteLine("Failed to get remote device versions info: "
+ ex.Message);
}
}
}
//----
private static bool GetCanConnectTo(BluetoothDeviceInfo device)
{
bool inRange;
Guid fakeUuid = new Guid("{F13F471D-47CB-41d6-9609-BAD0690BF891}");
try {
ServiceRecord[] records = device.GetServiceRecords(fakeUuid);
Debug.Assert(records.Length == 0, "Why are we getting any records?? len: " + records.Length);
inRange = true;
} catch (SocketException) {
inRange = false;
}
return inRange;
}
}
}

AT Commands to Send SMS not working in Windows 8.1

I have been researching now for more than two days, trying to make an app to send SMS using AT Command, I implemented few tutorials and projects available on web. Unluckily, none of them worked.
[https://docs.google.com/document/d/1VfBbMcKZsutP8Cwg2iu7Rqiyccks1J6N2ZEbkbxnCTU/preview ] This code gives me Command executed, but message is not sent.
Then I tried another project (I am using C# and Visual Studio 2013), which have following files, After execution the status is changes to Message Sent, but I do not receive Message. I am using HUAWEI Mobile Connect - 3G Application Interface GSM Modem
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CSharp_SMS
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form_SMS_Sender());
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CSharp_SMS
{
public partial class Form_SMS_Sender : Form
{
private SerialPort _serialPort;
public Form_SMS_Sender()
{
InitializeComponent();
}
private void buttonSend_Click(object sender, EventArgs e)
{
string number = textBoxNumber.Text;
string message = textBoxMessage.Text;
_serialPort = new SerialPort("COM17", 19200); //Replace "COM7" with corresponding port name
Thread.Sleep(1000);
_serialPort.Open();
Thread.Sleep(1000);
_serialPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
_serialPort.Write("AT+CMGS=\"" + number + "\"\r\n");
Thread.Sleep(1000);
_serialPort.Write(message + "\x1A");
Thread.Sleep(1000);
labelStatus.Text = "Status: Message sent";
_serialPort.Close();
}
}
}
Is there problem in the program? Did I missed any thing? Or, there's problem to run this in Windows 8.1, cause I also found that there is a program called MS HyperTerminal, which part of that is not clear to me.
I use SMSPDUlib
and code
private const string LT = "\r\n";
public void Auth(string pin)
{
lock (smsSendSync)
{
//Check if gateway is alive
lastSplit = SplitResponse(SendCommand("AT"));
if (!(lastSplit[lastSplit.Length - 1] == "OK"))
throw new OperationCanceledException("AT connection failed");
//Echo ON
lastSplit = SplitResponse(SendCommand("ATE1"));
if (!(lastSplit[lastSplit.Length - 1] == "OK"))
throw new OperationCanceledException("ATE command failed");
//Check echo
lastSplit = SplitResponse(SendCommand("AT"));
if (!(lastSplit.Length == 2 && lastSplit[1] == "OK"))
throw new OperationCanceledException("AT command failed");
//Verbose error reporting
lastSplit = SplitResponse(SendCommand("AT+CMEE=2"));
if (!(lastSplit.Length == 2 && lastSplit[1] == "OK"))
throw new OperationCanceledException("AT+CMEE command failed");
//Enter a PIN
lastSplit = SplitResponse(SendCommand("AT+CPIN?"));
if (!(lastSplit.Length == 3 && lastSplit[2] == "OK"))
throw new OperationCanceledException("AT+CPIN? command failed");
switch (lastSplit[1])
{
case "+CPIN: READY": //no need to enter PIN
break;
case "+CPIN: SIM PIN": //PIN requested
lastSplit = SplitResponse(SendCommand("AT+CPIN=" + pin));
string m_receiveData = String.Empty;
WaitForResponse(out m_receiveData);
if (m_receiveData == String.Empty)
throw new OperationCanceledException("PIN authentification timed out");
break;
default:
throw new OperationCanceledException("Unknown PIN request");
}
//Check if registered to a GSM network
lastSplit = SplitResponse(SendCommand("AT+CREG?"));
if (!(lastSplit.Length == 3 && lastSplit[2] == "OK"))
throw new OperationCanceledException("AT+CREG? command failed");
lastSplit = lastSplit[1].Split(new string[] {" ", ","}, StringSplitOptions.RemoveEmptyEntries);
if (!(lastSplit[2] == "1" || lastSplit[2] == "5"))
throw new OperationCanceledException("Not registered to a GSM network");
Debug.WriteLine("Authentification successfull");
}
}
private string[] SplitResponse(string response)
{
string[] split = response.Split(new string[] { LT }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < split.Length; i++)
split[i] = split[i].Trim();
return split;
}
public string SendCommand(string command)
{
string m_receiveData = string.Empty;
smsPort.ReadExisting(); //throw away any garbage
smsPort.WriteLine(command + LT);
WaitForResponse(out m_receiveData);
//Debug.WriteLine(m_receiveData);
return m_receiveData;
}
public string SendSms2(string phoneNumber, string message, bool flashMsg, SMS.SMSEncoding encoding)
{
if (phoneNumber.StartsWith("00"))
phoneNumber = "+" + phoneNumber.Substring(2);
if (phoneNumber.StartsWith("0"))
//replace with your national code
phoneNumber = "+386" + phoneNumber.Substring(1);
string StatusMessage = string.Empty;
SMS sms = new SMS(); //Compose PDU SMS
sms.Direction = SMSDirection.Submited; //Setting direction of sms
sms.Flash = flashMsg; //Sets the flash property of SMS
sms.PhoneNumber = phoneNumber.Replace(" ",""); //Set the recipient number
sms.MessageEncoding = encoding; //Sets the Message encoding for this SMS
sms.ValidityPeriod = new TimeSpan(4, 0, 0, 0); //Set validity period
sms.Message = message; //Set the SMS Message text
string sequence = sms.Compose() + CtrlZ; //Compile PDU unit
string sequenceLength = ((sequence.Length - 3) / 2).ToString();
lock (smsSendSync)
{
StatusMessage = SendCommand("AT+CMGS=" + sequenceLength) + " ";
Thread.Sleep(500);
StatusMessage += SendCommand(sequence);
}
Debug.WriteLine(StatusMessage);
if (StatusMessage.Contains("ERROR"))
throw new OperationCanceledException("Error sending SMS");
return StatusMessage;
}
Use Auth() to initialize modem and SendSms2() to send a SMS.
I used AT Commands in following format and it works.
public bool sendMsg(string smsid, string PhoneNo, string Message, string from, string to)
{
string recievedData;
bool isSend = false;
string text = "Hello " + to + ",\n" + Message + "\n\n" + from;
if (!port.IsOpen)
port = OpenPort();
recievedData = ExecCommand(port, "AT+CMGF=1", 400, "Failed to set message format.");
try
{
//string recievedData; // = ExecCommand(port, "AT", 3000, "No phone connected");
String command = "AT+CMGS=\"" + PhoneNo + "\"";
recievedData = ExecCommand(port, command, 1000, "Failed to accept phoneNo");
command = text + char.ConvertFromUtf32(26) + "\r";
recievedData = ExecCommand(port, command, 1000, "Failed to send message");
if (recievedData.Contains("OK"))
{
isSend = true;
}
else if (recievedData.Contains("ERROR"))
{
isSend = false;
}
}
catch (Exception ex)
{
MyLog.Write(new LogPacket(ex, DateTime.Now));
}
return isSend;
}

The notorious yet unaswered issue of downloading a file when windows security is required

There is a web site: http://site.domain.com which prompts for credentials with "windows security" dialog box. So I managed to use WebBrowser control to navigate to the page and send keystrokes to enter the password - I could not find another way around.
Now I came to the point where the website generates a link to a file I want to download, it looks like: http://site.domain.com/operations/reporting/csv/Report720_2553217.csv
I tried to use WebClient to download the file but it does nothing (br is my WebBrowser control):
WebClient wb = new WebClient();
wb.Headers.Add( br.Document.Cookie);
wb.DownloadFile(link, #"report.csv");
I have been trying to find a working solution to no avail. I know the web client is not authenticated so tried to use web browser's cookie but it does not work. The cookie looks as follows:
TLTUID=61FE48D8F9B910F9E930F42D6A03EAA6; TLTSID=0B2B8EE82688102641B7E768807FA8B2; s_cc=true; s_sq=%5B%5BB%5D%5D; ASPSESSIONIDQQSTRDQS=FNPJCODCEMGFIDHFLKDBEMHO
So I have two questions:
How to allow web client to download a file accessible from web browser's session. What am I doing wrong in the above code sample?
Is there an easy way to use WebBrowser solely to download and save that file to the path and filename of my choice? Or how to do it all using WebClient or something else?
Not possible, AFAIK. WebClient and WebBrowser use different layers to access web. WebClient uses WinHTTP, WebBrowser uses UrlMon. Thus, they would have separate sessions (including the authentication cache).
That's possible, just use any of UrlMon APIs to download the file, e.g. URLDownloadToFile or URLDownloadToCacheFile. I've just answered a similar question.
On a side note, you don't have to feed in keystrokes to provide authentication credentials. You can implement IAuthenticateEx on WebBrowser site object for this. Here is more info.
So this is the working solution which meets the requirements given in my question. It automatically navigates to the specified website, authenticates and downloads a generated report. I used this Q/A as an outline.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;
using System.Web;
using System.Security.Authentication;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.Win32;
using System.Runtime.CompilerServices;
using System.Security.Policy;
namespace margot_report
{
[ComImport,
Guid("00000112-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleObject
{
void SetClientSite(IOleClientSite pClientSite);
}
[ComImport,
Guid("00000118-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleClientSite
{
void SaveObject();
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
void GetContainer(object ppContainer);
void ShowObject();
void OnShowWindow(bool fShow);
void RequestNewObjectLayout();
}
[ComImport,
GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr
ppvObject);
}
[ComImport]
[Guid("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAuthenticate
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Authenticate(IntPtr phwnd,
[MarshalAs(UnmanagedType.LPWStr)] ref string pszUsername,
[MarshalAs(UnmanagedType.LPWStr)] ref string pszPassword);
}
class SelfAuthenticatingWebBrowser : WebBrowser, IOleClientSite, IAuthenticate, IServiceProvider
{
public static Guid IID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
public static Guid SID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
public const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
public const int S_OK = unchecked((int)0x00000000);
public void Authenticate(IntPtr phwnd, ref string pszUsername, ref string pszPassword)
{
Console.WriteLine("Authenticate");
pszUsername = Program.username; //
pszPassword = Program.password; //
//return S_OK;
}
public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
{
//Console.WriteLine("QueryService");
int nRet = guidService.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal
if (nRet == 0)
{
nRet = riid.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal
if (nRet == 0)
{
ppvObject = Marshal.GetComInterfaceForObject(this,
typeof(IAuthenticate));
return S_OK;
}
}
ppvObject = new IntPtr();
return INET_E_DEFAULT_ACTION;
}
public void SaveObject()
{
throw new NotImplementedException();
}
public void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk)
{
throw new NotImplementedException();
}
public void GetContainer(object ppContainer)
{
throw new NotImplementedException();
}
public void ShowObject()
{
throw new NotImplementedException();
}
public void OnShowWindow(bool fShow)
{
throw new NotImplementedException();
}
public void RequestNewObjectLayout()
{
throw new NotImplementedException();
}
public IComponent Component
{
get { throw new NotImplementedException(); }
}
public IContainer Container
{
get { throw new NotImplementedException(); }
}
public bool DesignMode
{
get { throw new NotImplementedException(); }
}
public string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
class Program
{
static bool send = true, verbose=false, clicked=false, submitted=false;
static int c = 0, t=0;
public static string filename, report, username, password;
/// <summary>
/// The URLMON library contains this function, URLDownloadToFile, which is a way
/// to download files without user prompts. The ExecWB( _SAVEAS ) function always
/// prompts the user, even if _DONTPROMPTUSER parameter is specified, for "internet
/// security reasons". This function gets around those reasons.
/// </summary>
/// <param name="pCaller">Pointer to caller object (AX).</param>
/// <param name="szURL">String of the URL.</param>
/// <param name="szFileName">String of the destination filename/path.</param>
/// <param name="dwReserved">[reserved].</param>
/// <param name="lpfnCB">A callback function to monitor progress or abort.</param>
/// <returns>0 for okay.</returns>
[DllImport("URLMON.DLL", EntryPoint = "URLDownloadToFileW", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int URLDownloadToFile(int pCaller, string srcURL,
string dstFile, int Reserved, int CallBack);
static void Main(string[] args)
{
// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://site.domain.com/operations/reporting/report-run.asp?reportid=720");
////webRequest.Proxy = webProxy;
string appname = Environment.GetCommandLineArgs()[0];
if (args.Count() < 1)
{
Console.WriteLine("Type: \"{0}\" -h for help on usage.\n", appname);
return;
}
if (args.Count() > 0)
foreach (var s in args)
if (s.Contains("-h") || s.Contains("/h") || s.Contains("-?") || s.Contains("/?"))
{
Console.WriteLine("\nUsage: {0} [-rfupv] <values>\n", appname);
Console.WriteLine("\n -r report_link ");
Console.WriteLine(" -f output_file ");
Console.WriteLine(" -u username ");
Console.WriteLine(" -p password ");
Console.WriteLine(" -t time_delay - seconds to wait before sending key strokes");
Console.WriteLine(" -v verbose output to console (for debugging)");
Console.WriteLine(" -h|? Display this info and exit.");
return;
}
try
{
if (args.Any(x => x.Contains("-f")))
{
int i = 0;
while (!args[i].Contains("-f")) i++;
filename =args[i + 1];
}
else filename = "report.csv";
if (args.Any(x => x.Contains("-r")))
{
int i = 0;
while (!args[i].Contains("-r")) i++;
report = args[i + 1];
}
else report = "http://site.domain.com/operations/reporting/report-run.asp?reportid=720";
if (args.Any(x => x.Contains("-u")))
{
int i = 0;
while (!args[i].Contains("-u")) i++;
username = args[i + 1];
}
else username = "";
if (args.Any(x => x.Contains("-p")))
{
int i = 0;
while (!args[i].Contains("-p")) i++;
password = args[i + 1];
}
else password = "";
if (args.Any(x => x.Contains("-t")))
{
int i = 0;
while (!args[i].Contains("-t")) i++;
t = int.Parse(args[i + 1]);
}
else t = 5;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
if (ex.InnerException != null) Console.WriteLine(ex.InnerException.Message);
return;
}
///////////////////////////////
//////////////////////////////////////////////////////
Console.WriteLine("start");
var th = new Thread(() => {
//WebBrowser
var wb = new SelfAuthenticatingWebBrowser(); // WebBrowser();
wb.Show(); Console.WriteLine(wb.DocumentText);
Console.WriteLine(wb.DocumentText);
wb.DocumentCompleted += browser_DocumentCompleted;
wb.NewWindow += browser_newWindow;
wb.ControlAdded += browser_ControlAdded ;
wb.LostFocus += browser_LostFocus;
wb.Navigating += browser_Navigating;
wb.FileDownload += browser_FileDownload;
//wb.Site = new MySitex();
//Console.WriteLine(wb.Site.GetService(typeof(IAuthenticateEx)));//wb.Site.Name
Console.WriteLine(wb.AllowNavigation);
wb.Navigate("about:blank");
object obj = wb.ActiveXInstance;
IOleObject oc = obj as IOleObject;
oc.SetClientSite(wb as IOleClientSite);
//this.Site = this as ISite;
System.IntPtr ppvServiceProvider;
IServiceProvider sp = wb as IServiceProvider;
sp.QueryService(ref SelfAuthenticatingWebBrowser.SID_IAuthenticate, ref SelfAuthenticatingWebBrowser.IID_IAuthenticate, out ppvServiceProvider);
wb.Navigate(report);
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
Console.WriteLine("end");
}
static void browser_Navigating(object sender, EventArgs e)
{
Console.WriteLine("navigating..." );
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
//foreach (var x in s.Controls)
// Console.WriteLine(x.ToString());
//foreach(Form x in Application.OpenForms)
// Console.WriteLine(x.Name);
if (false)//(send)
{
send = false;
var thekeys = new Thread(() =>
{
Thread.Sleep(t*1000);
if (username != "")
{
Console.WriteLine("sending username key strokes");
SendKeys.SendWait(username);
SendKeys.SendWait("{TAB}");
Console.WriteLine("sent");
}
if (password != "")
{
Console.WriteLine("sending password key strokes");
SendKeys.SendWait(password);
SendKeys.SendWait("{ENTER}");
Console.WriteLine("sent");
}
});
thekeys.Start();
}
}
static void browser_FileDownload(object sender, EventArgs e)
{
if(verbose) Console.WriteLine("FileDownload : " + e.ToString());
var s = sender as WebBrowser;
if (verbose) Console.WriteLine(s.DocumentTitle + s.Name + s.Url); //Console.ReadKey();
}
static void browser_LostFocus(object sender, EventArgs e)
{
Console.WriteLine("lost focus : " + e.ToString());
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
}
static void browser_ControlAdded(object sender, ControlEventArgs e)
{
Console.WriteLine("control added : " + e.ToString());
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
}
static void browser_newWindow(object sender, CancelEventArgs e)
{
Console.WriteLine("new : " + e.ToString());
var s = sender as WebBrowser;
Console.WriteLine(s.DocumentTitle + s.Name);
}
static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var br = sender as WebBrowser;
if (e.Url.ToString()=="about:blank") return;
if (br.Url == e.Url)
{
Console.WriteLine("Navigated to {0}", e.Url);
if (e.Url.ToString() == "http://site.domain.com/operations/reporting/report-generate.asp") submitted = true;
if(verbose) Console.WriteLine(br.DocumentText);
//Console.WriteLine(br.Document.Cookie);
if(!clicked)
foreach (HtmlElement x in br.Document.All)
{
// if (x.All == null)
//Console.WriteLine("|{0} {1} {2}| [{3}]\n", x.Id, x.Name, ".",x.GetAttribute("value"));
if (x.Name == "format" && x.GetAttribute("value") == "C") { Console.WriteLine("\n C L I C K !\n"); x.InvokeMember("click"); Thread.Sleep(1000); clicked = true; }
//else foreach (HtmlElement y in x.Document.All)
// Console.WriteLine("|{0} {1} {2}| [{3}]\n", y.Id, y.Name, y.OuterHtml, x.InnerText);
}
if (clicked && !submitted)
{
Console.WriteLine("submitting the report");
if (verbose) Console.WriteLine(" function at: {0}", br.DocumentText.IndexOf("function runReport()"));
//var newtext = br.DocumentText.Replace("value=\"R\" checked", "value=\"R\" ").Replace("value=\"C\"", "value=\"C\" checked");
//Console.WriteLine(" function at: {0}", br.DocumentText.IndexOf("function runReport()"));
br.Document.InvokeScript("runReport");
Console.WriteLine("done");
//Console.WriteLine(br.DocumentText);
}
//if (c == 1)
{
//Console.WriteLine(br.DocumentText);
if (verbose) Console.WriteLine(br.DocumentText.IndexOf("http://"));
if (verbose) Console.WriteLine(br.DocumentText.IndexOf(".csv"));
}
if (verbose) Console.WriteLine("c = {0}", c);
//http://site.domain.com/operations/reporting/csv/Report714_4045373.csv
if (submitted)
{
int start = br.DocumentText.IndexOf("csv/Report");
int end = 0; if (start >= 0) end = br.DocumentText.IndexOf(".csv", start);
if (start > 0 && end > start)
{
if (verbose) Console.WriteLine(br.DocumentText.Substring(start, end - start));
string link = "http://site.domain.com/operations/reporting/" + br.DocumentText.Substring(start, end - start) + ".csv";
Console.WriteLine(link);
//Console.WriteLine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
//Console.WriteLine(System.IO.Directory.GetCurrentDirectory());
if (URLDownloadToFile(0, link, filename, 0, 0) == 0)
Console.WriteLine("The report has been saved as {0}", filename);
else
Console.WriteLine("There was a problem with downloading/saving the report {0}", report);
Application.ExitThread();
}
}
if (verbose) Console.WriteLine("cookies ? {0}, {1}, {2}", br.Document.Cookie == null, br.Document.Cookie == "", br.Document.Cookie);
c++;
if(c>4) Application.ExitThread(); // Stops the thread
}
}
}
}

IRCBot C# connection issues

I am having an issue with my IRC Bot I am trying to write in c# just as a way to help get my head around the IRC protocol, I am planning on writing a client/server in the future but as you can prolly guess I am far off this :P
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
namespace LolBot
{
struct IRCConfig
{
public string server;
public int port;
public string nick;
public string name;
}
class IRCBot
{
TcpClient IRCConnection = null;
IRCConfig config;
NetworkStream ns = null;
StreamReader sr = null;
StreamWriter sw = null;
public IRCBot(IRCConfig config)
{
this.config = config;
try
{
IRCConnection = new TcpClient(config.server, config.port);
}
catch
{
Console.WriteLine("Connection Error");
}
try
{
ns = IRCConnection.GetStream();
sr = new StreamReader(ns);
sw = new StreamWriter(ns);
sendData("USER", config.nick + config.name);
sendData("NICK", config.nick);
}
catch
{
Console.WriteLine("Communication error");
}
finally
{
if (sr != null)
sr.Close();
if (sw != null)
sw.Close();
if (ns != null)
ns.Close();
if (IRCConnection != null)
IRCConnection.Close();
}
}
public void sendData(string cmd, string param)
{
if (param == null)
{
sw.WriteLine(cmd);
sw.Flush();
Console.WriteLine(cmd);
}
else
{
sw.WriteLine(cmd + " " + param);
sw.Flush();
Console.WriteLine(cmd + " " + param);
}
}
public void IRCWork()
{
string[] ex;
string data;
bool shouldRun = true;
while (shouldRun)
{
data = sr.ReadLine();
Console.WriteLine(data);
char[] charSeparator = new char[] { ' ' };
ex = data.Split(charSeparator, 5);
if (ex[0] == "PING")
{
sendData("PONG", ex[1]);
}
if (ex.Length > 4) //is the command received long enough to be a bot command?
{
string command = ex[3]; //grab the command sent
switch (command)
{
case ":!join":
sendData("JOIN", ex[4]); //if the command is !join send the "JOIN" command to the server with the parameters set by the user
break;
case ":!say":
sendData("PRIVMSG", ex[2] + " " + ex[4]); //if the command is !say, send a message to the chan (ex[2]) followed by the actual message (ex[4]).
break;
case ":!quit":
sendData("QUIT", ex[4]); //if the command is quit, send the QUIT command to the server with a quit message
shouldRun = false; //turn shouldRun to false - the server will stop sending us data so trying to read it will not work and result in an error. This stops the loop from running and we will close off the connections properly
break;
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
IRCConfig conf = new IRCConfig();
conf.name = "LolBot";
conf.nick = "LolBot";
conf.port = 6667;
conf.server = "irc.strictfp.com";
new IRCBot(conf);
Console.WriteLine("Bot quit/crashed");
Console.ReadLine();
}
}
}
Whenever I execute the Bot, it comes up with:
USER AspiBot google.com google.com :AspiBot
NICK AspiBot
Bot quit/crashed
I don't really understand why it is quiting before connecting to the server and I am also looking on how to set it up to join a channel, I am aware that I need to use JOIN but I'm not sure how to implent it.
You should probably not do so much in the constructor, but the problem you are encountering here is that you are not calling IRCWork() after newing up the bot.
var bot = new IRCBot(conf);
bot.IRCWork();
EDIT You are also closing all of your connections in the finally block of your constructor, so IRCWork() isn't going to work anyway. Try implementing IDisposable, and putting your close logic in Dispose():
using (var bot = new IRCBot(conf))
{
bot.IRCWork();
}
Quick refactor of posted code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
namespace LolBot
{
internal struct IRCConfig
{
public string server;
public int port;
public string nick;
public string name;
}
internal class IRCBot : IDisposable
{
private TcpClient IRCConnection = null;
private IRCConfig config;
private NetworkStream ns = null;
private StreamReader sr = null;
private StreamWriter sw = null;
public IRCBot(IRCConfig config)
{
this.config = config;
}
public void Connect()
{
try
{
IRCConnection = new TcpClient(config.server, config.port);
}
catch
{
Console.WriteLine("Connection Error");
throw;
}
try
{
ns = IRCConnection.GetStream();
sr = new StreamReader(ns);
sw = new StreamWriter(ns);
sendData("USER", config.nick + config.name);
sendData("NICK", config.nick);
}
catch
{
Console.WriteLine("Communication error");
throw;
}
}
public void sendData(string cmd, string param)
{
if (param == null)
{
sw.WriteLine(cmd);
sw.Flush();
Console.WriteLine(cmd);
}
else
{
sw.WriteLine(cmd + " " + param);
sw.Flush();
Console.WriteLine(cmd + " " + param);
}
}
public void IRCWork()
{
string[] ex;
string data;
bool shouldRun = true;
while (shouldRun)
{
data = sr.ReadLine();
Console.WriteLine(data);
char[] charSeparator = new char[] {' '};
ex = data.Split(charSeparator, 5);
if (ex[0] == "PING")
{
sendData("PONG", ex[1]);
}
if (ex.Length > 4) //is the command received long enough to be a bot command?
{
string command = ex[3]; //grab the command sent
switch (command)
{
case ":!join":
sendData("JOIN", ex[4]);
//if the command is !join send the "JOIN" command to the server with the parameters set by the user
break;
case ":!say":
sendData("PRIVMSG", ex[2] + " " + ex[4]);
//if the command is !say, send a message to the chan (ex[2]) followed by the actual message (ex[4]).
break;
case ":!quit":
sendData("QUIT", ex[4]);
//if the command is quit, send the QUIT command to the server with a quit message
shouldRun = false;
//turn shouldRun to false - the server will stop sending us data so trying to read it will not work and result in an error. This stops the loop from running and we will close off the connections properly
break;
}
}
}
}
public void Dispose()
{
if (sr != null)
sr.Close();
if (sw != null)
sw.Close();
if (ns != null)
ns.Close();
if (IRCConnection != null)
IRCConnection.Close();
}
}
internal class Program
{
private static void Main(string[] args)
{
IRCConfig conf = new IRCConfig();
conf.name = "LolBot";
conf.nick = "LolBot";
conf.port = 6667;
conf.server = "irc.strictfp.com";
using (var bot = new IRCBot(conf))
{
bot.Connect();
bot.IRCWork();
}
Console.WriteLine("Bot quit/crashed");
Console.ReadLine();
}
}
}

SMS connecting to a phone from C# and getting a response

I wrote code to send an SMS using my GSM phone which is attached to the computer through COM port. The code is below.
The problem is I do see that it is in the outbox of the phone and it actually appears to have been sent, but when I contact the recipient they say that I have not received the message.
I test the phone, and I create and send a message using only the phone and it works perfectly. However, when I do this with my code, it APPEARS to have been sent, and I am getting all the correct AT COMMAND responses from the phone, but the message is actually NOT sent.
Here is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO.Ports;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
SerialPort serialPort1;
int m_iTxtMsgState = 0;
const int NUM_MESSAGE_STATES = 4;
const string RESERVED_COM_1 = "COM1";
const string RESERVED_COM_4 = "COM4";
public Form1()
{
InitializeComponent();
this.Closing += new CancelEventHandler(Form1_Closing);
}
private void Form1_Load(object sender, EventArgs e)
{
serialPort1 = new SerialPort(GetUSBComPort());
if (serialPort1.IsOpen)
{
serialPort1.Close();
}
serialPort1.Open();
//ThreadStart myThreadDelegate = new ThreadStart(ReceiveAndOutput);
//Thread myThread = new Thread(myThreadDelegate);
//myThread.Start();
this.serialPort1.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
}
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
serialPort1.Close();
}
private void SendLine(string sLine)
{
serialPort1.Write(sLine);
sLine = sLine.Replace("\u001A", "");
consoleOut.Text += sLine;
}
public void DoWork()
{
ProcessMessageState();
}
public void ProcessMessageState()
{
switch (m_iTxtMsgState)
{
case 0:
m_iTxtMsgState = 1;
SendLine("AT\r\n"); //NOTE: SendLine must be the last thing called in all of these!
break;
case 1:
m_iTxtMsgState = 2;
SendLine("AT+CMGF=1\r\n");
break;
case 2:
m_iTxtMsgState = 3;
SendLine("AT+CMGW=" + Convert.ToChar(34) + "+9737387467" + Convert.ToChar(34) + "\r\n");
break;
case 3:
m_iTxtMsgState = 4;
SendLine("A simple demo of SMS text messaging." + Convert.ToChar(26));
break;
case 4:
m_iTxtMsgState = 5;
break;
case 5:
m_iTxtMsgState = NUM_MESSAGE_STATES;
break;
}
}
private string GetStoredSMSID()
{
return null;
}
/* //I don't think this part does anything
private void serialPort1_DataReceived_1(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string response = serialPort1.ReadLine();
this.BeginInvoke(new MethodInvoker(() => textBox1.AppendText(response + "\r\n")));
}
*/
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
Thread.Sleep(500);
char[] msg;
msg = new char[613];
int iNumToRead = serialPort1.BytesToRead;
serialPort1.Read(msg, 0, iNumToRead);
string response = new string(msg);
this.BeginInvoke(new MethodInvoker(() => textBox1.AppendText(response + "\r\n")));
serialPort1.DiscardInBuffer();
if (m_iTxtMsgState == 4)
{
int pos_cmgw = response.IndexOf("+CMGW:");
string cmgw_num = response.Substring(pos_cmgw + 7, 4);
SendLine("AT+CMSS=" + cmgw_num + "\r\n");
//stop listening to messages received
}
if (m_iTxtMsgState < NUM_MESSAGE_STATES)
{
ProcessMessageState();
}
}
catch
{ }
}
private void button1_Click(object sender, EventArgs e)
{
m_iTxtMsgState = 0;
DoWork();
}
private void button2_Click(object sender, EventArgs e)
{
string[] sPorts = SerialPort.GetPortNames();
foreach (string port in sPorts)
{
consoleOut.Text += port + "\r\n";
}
}
private string GetUSBComPort()
{
string[] sPorts = SerialPort.GetPortNames();
foreach (string port in sPorts)
{
if (port != RESERVED_COM_1
&& port != RESERVED_COM_4)
{
return port;
}
}
return null;
}
}
This is my code that works (tested) with U9 Telia cellular modem:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Configuration;
using UsbEject.Library;
using Utils;
namespace Hardware
{
public class TeliaModem : IDisposable
{
public delegate void NewSmsHandler(InboundSMS sms);
public event NewSmsHandler OnNewSMS;
#region private data
System.IO.Ports.SerialPort modemPort;
Timeouter _lastModemKeepAlive;
private delegate void DataReceivedDelegate();
private DataReceivedDelegate dataReceivedDelegate;
Queue<OutboundSMS> _outSmses = new Queue<OutboundSMS>();
enum ModemState
{
Error = -1, NotInitialized, PowerUp, Initializing, Idle,
SendingSMS, KeepAliveAwaitingResponse
};
Timeouter ModemStateTimeouter = new Timeouter(timeout_s: 10, autoReset: false);
ModemState _modemState = ModemState.NotInitialized;
ModemState CurrentModemState
{
get
{
return _modemState;
}
set
{
_modemState = value;
ModemStateTimeouter.Reset();
NihLog.Write(NihLog.Level.Debug, "State changed to: " + value.ToString());
}
}
private System.Windows.Forms.Control _mainThreadOwnder;
#endregion
public TeliaModem(System.Windows.Forms.Control mainThreadOwnder)
{
_mainThreadOwnder = mainThreadOwnder;
dataReceivedDelegate = new DataReceivedDelegate(OnDataReceived);
}
public void SendSMS(string phone, string text)
{
_outSmses.Enqueue(new OutboundSMS(phone, text));
HeartBeat();
}
private void SendSmsNow()
{
OutboundSMS sms = _outSmses.Peek();
sms.Attempt++;
if (sms.Attempt > sms.MaxTries)
{
NihLog.Write(NihLog.Level.Error, "Failure to send after " + sms.MaxTries + " tries");
_outSmses.Dequeue();
return;
}
NihLog.Write(NihLog.Level.Info, "Sending SMS: " + sms.ToString());
WriteToModem("AT+CMGS=\"" + sms.Destination + "\"\r");
System.Threading.Thread.Sleep(500);
WriteToModem(sms.Text);
byte[] buffer = new byte[1];
buffer[0] = 26; // ^Z
modemPort.Write(buffer, offset:0, count:1);
CurrentModemState = ModemState.SendingSMS;
}
public void Dispose()
{
UninitModem();
}
public void HeartBeat()
{
if (CurrentModemState == ModemState.NotInitialized)
{
TryInitModem();
return;
}
if (IsTransitionalState(CurrentModemState) && ModemStateTimeouter.IsTimedOut())
{
NihLog.Write(NihLog.Level.Error, "Modem error. Timed out during " + CurrentModemState);
CurrentModemState = ModemState.Error;
return;
}
if (CurrentModemState == ModemState.Idle && _lastModemKeepAlive.IsTimedOut())
{
// Send keepalive
WriteToModem("AT\r");
CurrentModemState = ModemState.KeepAliveAwaitingResponse;
return;
}
if (CurrentModemState == ModemState.Error)
{
NihLog.Write(NihLog.Level.Debug, "Reenumerating modem...");
UninitModem();
return;
}
if (_outSmses.Count != 0 && CurrentModemState == ModemState.Idle)
{
SendSmsNow();
return;
}
}
private string pendingData;
private void OnDataReceived()
{
// Called in the main thread
string nowWhat = modemPort.ReadExisting();
pendingData += nowWhat;
string[] lines = pendingData.Split(new string[] { "\r\n" }, StringSplitOptions.None);
if (lines.Length == 0)
{
pendingData = string.Empty;
return;
}
else
{
pendingData = lines[lines.Length - 1];
}
// This happens in main thread.
for (int i = 0; i < lines.Length - 1; i++)
{
string line = lines[i];
if (line.Length >= 5 && line.Substring(0, 5) == "+CMT:")
{
// s+= read one more line
if (i == lines.Length - 1) // no next line
{
pendingData = line + "\r\n" + pendingData; // unread the line
continue;
}
string line2 = lines[++i];
NihLog.Write(NihLog.Level.Debug, "RX " + line);
NihLog.Write(NihLog.Level.Debug, "RX " + line2);
InboundSMS sms = new InboundSMS();
sms.ParseCMT(line, line2);
if(OnNewSMS != null)
OnNewSMS(sms);
}
else // Not a composite
NihLog.Write(NihLog.Level.Debug, "RX " + line);
if (line == "OK")
{
OnModemResponse(true);
}
else if (line == "ERROR")
{
OnModemResponse(false);
NihLog.Write(NihLog.Level.Error, "Modem error");
}
}
}
private void ProcessSmsResult(bool ok)
{
if (!ok)
{
OutboundSMS sms = _outSmses.Peek();
if (sms.Attempt < sms.MaxTries)
{
NihLog.Write(NihLog.Level.Info, "Retrying sms...");
return;
}
NihLog.Write(NihLog.Level.Error, "Failed to send SMS: " + sms.ToString());
}
_outSmses.Dequeue();
}
private void OnModemResponse(bool ok)
{
if (CurrentModemState == ModemState.SendingSMS)
ProcessSmsResult(ok);
if (!ok)
{
NihLog.Write(NihLog.Level.Error, "Error during state " + CurrentModemState.ToString());
CurrentModemState = ModemState.Error;
return;
}
switch (CurrentModemState)
{
case ModemState.NotInitialized:
return;
case ModemState.PowerUp:
WriteToModem("ATE0;+CMGF=1;+CSCS=\"IRA\";+CNMI=1,2\r");
CurrentModemState = ModemState.Initializing;
break;
case ModemState.Initializing:
case ModemState.SendingSMS:
case ModemState.KeepAliveAwaitingResponse:
CurrentModemState = ModemState.Idle;
break;
}
}
private void CloseU9TelitNativeApp()
{
bool doneSomething;
do
{
doneSomething = false;
Process[] processes = Process.GetProcessesByName("wirelesscard");
foreach (Process p in processes)
{
p.CloseMainWindow();
doneSomething = true;
NihLog.Write(NihLog.Level.Info, "Killed native U9 app");
System.Threading.Thread.Sleep(1000); // Will not wait if no native app is started
}
} while (doneSomething);
}
void WriteToModem(string s)
{
modemPort.Write(s);
NihLog.Write(NihLog.Level.Debug, "TX " + s);
}
void UninitModem()
{
if (modemPort != null)
modemPort.Dispose();
modemPort = null;
CurrentModemState = ModemState.NotInitialized;
}
private bool IsTransitionalState(ModemState ms)
{
return ms == ModemState.Initializing
|| ms == ModemState.SendingSMS
|| ms == ModemState.PowerUp
|| ms == ModemState.KeepAliveAwaitingResponse;
}
Timeouter _initFailureTimeout =
new Timeouter(timeout_s: 10, autoReset:false, timedOut:true);
void TryInitModem()
{
// Try pistoning the modem with higher frequency. This does no harm (such as redundant logging)
PrepareU9Modem(); // Will do nothing if modem is okay
if (!_initFailureTimeout.IsTimedOut())
return; // Don't try too frequently
if (modemPort != null)
return;
const string modemPortName = "Basecom HS-USB NMEA 9000";
const int speed = 115200;
string portName = Hardware.Misc.SerialPortFromFriendlyName(modemPortName);
if (portName == null)
{
NihLog.Write(NihLog.Level.Error, "Modem not found (yet). ");
_initFailureTimeout.Reset();
return;
}
NihLog.Write(NihLog.Level.Info, string.Format("Found modem port \"{0}\" at {1}", modemPortName, portName));
modemPort = new System.IO.Ports.SerialPort(portName, speed);
modemPort.ReadTimeout = 3000;
modemPort.NewLine = "\r\n";
modemPort.Open();
modemPort.DiscardInBuffer();
modemPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(delegate { _mainThreadOwnder.Invoke(dataReceivedDelegate); }); // called in different thread!
_lastModemKeepAlive = new Timeouter(60, true);
WriteToModem("AT+CFUN=1\r");
CurrentModemState = ModemState.PowerUp;
}
void CheatU9Telit()
{
// U9 telit appears as USB CDrom on the bus, until disk eject is sent.
// Then, it reappears as normal stuff.
VolumeDeviceClass volumeDeviceClass = new VolumeDeviceClass();
foreach (Volume device in volumeDeviceClass.Devices)
{
if (device.FriendlyName == "PCL HSUPA Modem USB Device")
{
NihLog.Write(NihLog.Level.Info, "Trying to initialize: " + device.FriendlyName);
device.EjectCDRomNoUI();
}
}
}
void PrepareU9Modem()
{
CloseU9TelitNativeApp(); // Closes the autorun native app
CheatU9Telit();
}
}
public class OutboundSMS
{
public string Destination;
public string Text;
public int MaxTries;
public int Attempt = 0;
public OutboundSMS(string dest, string txt)
{
Destination = dest;
Text = txt;
MaxTries = 3;
}
override public string ToString()
{
if(Attempt > 1)
return string.Format("\"{0}\" to {1}, attempt {2}",
Text, Destination, Attempt);
else
return string.Format("\"{0}\" to {1}",
Text, Destination);
}
}
public class InboundSMS
{
public string SourcePhone;
public DateTime ReceiveTime;
public string Text;
public void ParseCMT(string line1, string line2)
{
string[] fields = line1.Split(new char[] { ',', ' ', '/', ':', '"' });
if (fields.Length < 12)
throw new ApplicationException("CMT message too short. Expected 2 fields");
SourcePhone = fields[3];
ReceiveTime = DateTime.Parse("20" + fields[7] + "-" + fields[8] + "-" + fields[9] + " " + fields[10] + ":" + fields[11] + ":" + fields[12].Substring(0, 2)); //test carefully
Text = line2;
}
};
}
Usage example in a winforms application:
Hardware.TeliaModem _modem;
public Form1()
{
InitializeComponent();
_modem = new Hardware.TeliaModem(this);
_modem.OnNewSMS += new Hardware.TeliaModem.NewSmsHandler(ProcessNewSMS);
_timer.Interval = 1000; // milliseconds
_timer.Tick += new EventHandler(OnTimerTick);
_timer.Start();
}
To send an SMS:
_modem.SendSMS(sms.SourcePhone, "Aircon is now " + BoolToString.ON_OFF(_aircon.On));
On timer event, once every second:
private void OnTimerTick(object o, EventArgs e)
{
_modem.HeartBeat();
}
This is registered as Winforms timer handler, so that modem will not have a thread.
Some utility classes used:
namespace Utils
{
public class StopWatch
{
protected DateTime _resetTime;
public StopWatch() { Reset(); }
public void Reset() { _resetTime = DateTime.Now; }
public double TotalSeconds { get { return (DateTime.Now - _resetTime).TotalSeconds; } }
public TimeSpan Time { get { return DateTime.Now - _resetTime; } }
};
public class Timeouter : StopWatch
{
private bool _autoReset;
private double _timeout_s;
public Timeouter(double timeout_s, bool autoReset, bool timedOut = false)
{
_timeout_s = timeout_s;
_autoReset = autoReset;
if (timedOut)
_resetTime -= TimeSpan.FromSeconds(_timeout_s + 1); // This is surely timed out, as requested
}
public bool IsTimedOut()
{
if (_timeout_s == double.PositiveInfinity)
return false;
bool timedout = this.TotalSeconds >= _timeout_s;
if (timedout && _autoReset)
Reset();
return timedout;
}
public void Reset(double timeout_s) { _timeout_s = timeout_s; Reset(); }
public double TimeLeft { get { return _timeout_s - TotalSeconds; } }
}
}
I implemented this in order to turn on air conditioner with SMS (yeah, I live in a hot country). It works. Please feel free to use any of this code.
Enjoy.
Microsoft provides a pretty decent VB.Net example in a KB article "How to access serial and parallel ports by using Visual Basic .NET". I'm not sure what your phone returns, however, if you change the buffer loop in the example, you can at least print out the reply:
MSComm1.Output = "AT" & Chr(13)
Console.WriteLine("Send the attention command to the modem.")
Console.WriteLine("Wait for the data to come back to the serial port...")
' Make sure that the modem responds with "OK".
' Wait for the data to come back to the serial port.
Do
Buffer = Buffer & MSComm1.Input
Console.WriteLine("Found: {0}", Buffer)
Loop Until InStr(Buffer, "OK" & vbCrLf)
GSMComm is a C# library that will allow you to easily interact with a GSM mobile in text or PDU mode. (The site also has a bunch of testing utilities)
Working with GSM modem to send SMS has never been a good idea as such. Here's a checklist to make sure your SMS is sent out properly.
You are sending the SMS in text mode. Try sending it in PDU mode.
Try this library http://phonemanager.codeplex.com/
Do you change SMSC number before sending out the SMS, if so make sure the SMSC is correct.
Also make sure your SIM card has enough credits to let you send outbound SMS.
Check the network status especially when you're sending out SMS from your program. This might be a problem.
I recommend you checkout the Lite edition of NowSMS gateway that comes for free and lets you work with GSM modem very continently. NowSMS will give you api abstraction over a GSM modem connection, so you wil just need to call the Http Api of NowSMS gateway, rest will be taken care by the NowSMS gateway.
Above all this, if your end-users are going to remain internet connected while using your application or if your application is web-based and hosted over internet, I strongly recoomend to do away with GSM modem option and opt-in for reliable Http SMS gateway service providers.

Categories