Connection between 2 computers via dial up modem without internet in c# - c#

Hi Is there any way to connecting to computers via Dial Modem without internet?
Like windows Hyper terminal.
making connection sending files between computers.
Just Connection Between two Computers Directly and sending FIle.

Yes.
Assuming the modems are connected via a serial port (or emulate being connected via a serial port): you'll need one modem set up (learn your AT commands!) to listen for and answer incoming calls, and the other to dial the first.
You can then treat the pair as a rather long serial link.
However getting everything to work reliably is more of an art than a science, and something that is so rarely done today that much of it is forgotten. The last time I worked with modems in this way was more than fifteen years ago.

The way we used to do it back in the olden days was with a null-modem cable. We even used to do "networked" gaming that way, back in the day.
This is bascially an RS-232 cable with the receive and transmit pins crosswired. I still see some adapters around, so it shouldn't be too tough to get hold of one.
Much later some people created SLIP (Serial Line IP) to enable a serial line to act as a carrier for the entire TCP/IP stack. A bit later PPP was introduced as an improvement. I think SLIP is still available for most platforms, and PPP exists on every platform that can do dial-up internet.
So if the question basically boils down to wanting to network two computers via PPP without going through somebody else's dial-up server (like Earthlink), what you need is to install a PPP server on one of the two machines. They come with most Linux distros. For Windows you will have to go look. I'd help, but my corporate blocker is being overexuberant again.

Someone has written an XModem implementation in C# here: http://trackday.cc/b2evo/blog2.php/2007/08/02/net-xmodem It may help with what you're after.

One thing that's not clear from your question is whether you are attempting to directly connect two machines in the same physical location with a cable, or if you are attempting to dial in to one from the other over a PSTN.
If they are in the same place, eliminate the modem from the equation. This reduces complexity significantly.
If they are in separate locations (ie, dialing over an honest-to-God dial-up connection), there is some code here that might help you. The article talks about a Bluetooth or GPRS modem, but the core of it is about sending AT commands which can be used to talk to any AT-command set-compatible device. It might get you going in the right direction.
Update
See http://msdn2.microsoft.com/en-us/system.io.ports.serialport(VS.80).aspx
Since a modem should be attached to a COM port (COM1-COM12) even it is an internal modem, you should be able to use the .NET framework's SerialPort class to open the port, send AT commands, etc. Once you have an open connection, you could use the XModem library to transfer files, or straight serial for regular communications.
Do you need an IP stack, or are you happy with a straight serial protocol?

You can quite easily setup dial-up network connections within Windows that require the use of a modem (its under the option for setting up a VPN, but you can set it for just a dial up).
So I would assume that you can then map a network location to it for use by your C# code.
As already stated at least one of the modems must be on and listening for a connection.
* edit *
I believe that the following code will trigger a dial-up connection that has been placed within Network Connections
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo(#"c:\Local Area Connection 2 - Shortcut");
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
For link placed at c:\ drive and named "Local Area Connection 2 - Shortcut"
You could then ping the destination to see if its connected.
Ultimately though I think that your best solution may be to use RAS.
Have a look here at Codeplex: DotRAS
You can then use the following code:
RasDialer dialer = new RasDialer();
bool connected = false;
foreach (RasConnection connection in dialer.GetActiveConnections())
{
if (connection.EntryName == "MyFriendsPC")
{
connected = true;
break;
}
}
if (!connected) {
dialer.EntryName = "MyFriendsPC";
dialer.Dial();
// If you need to provide credentials, use the Dial(NetworkCredential) overload that's available.
}
This example assumes you already have an entry named MyFriendsPC in the default phone book. If you do not and need to create this connection programmatically, you can use the RasPhoneBook component for that.
RasPhoneBook pbk = new RasPhoneBook();
pbk.Open(); // This will open the phone book in the All Users profile.
RasEntry entry = new RasEntry("MyFriendsPC");
If you'd rather use the default settings for the connection you can use one of the static methods on the RasEntry class, or manually configured the connection here.
pbk.Entries.Add(entry);
Once the entry has been added to the collection, it will immediately be added into the phone book.

I recently wanted to connect a dial-up POS terminal to an analog modem. This is not difficult, but you need to introduce a 9-volt battery and a 200mA resistor in parallel for the modems to connect. https://www.youtube.com/watch?v=luarFqislIc describes the approach (skip to 11:30 to see the circuit). Without the battery and resistor to provide the loop current (about 18mA), the modems will not negotiate a connection (you'll hear the modem after entering ATA to answer, but you won't hear the final part of the modem negotiation). With the loop current, the modems will connect. The video even shows ZModem being used to transfer a file from one PC to the other.
One final item not mentioned in the video is with this circuit, there is no dial tone. To get around this, enable blind dialing (ATX1) on the calling modem. Also, since there are no rings with this approach, setting the receiving modem to auto-answer (ATS0=1) won't work. You have to enter ATA on the receiving modem to answer.

Related

Serial Port Disconnect with exception: system.invalidoperationexception in system.dll [duplicate]

I got a little problem with a USB Barcode Scanner.
I am using the Scanner with the "SerialPort" class:
this._barcodeScanner = new SerialPort(comPort, 9600, Parity.None, 8, StopBits.One) { Handshake = Handshake.None, ReadTimeout = 500, WriteTimeout = 500 };
this._barcodeScanner.Open();
this._barcodeScanner.DataReceived += BarcodeScannerCallback;
If I unplug the USB Device while it´s opened via the "SerialPort" class, I can´t close the software properly and the virtual port stays open for all eternity or till I reboot the whole computer.
So my question is, is there any way to close the virtual port after I unplugged the device via C# code?
Greetings
[edit #1]
Alrighty, some more code:
This way I am checking every 10 seconds if the device is plugged in:
private bool CheckUsbDeviceAvailability()
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSSerial_PortName WHERE PortName = '" + this.PortName + "'");
if (searcher.Get().Count > 0)
return true;
return false;
}
Thats the Callback-Event of the Serial Port:
void BarcodeScannerCallback(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(500);
string data = this._barcodeScanner.ReadExisting().Replace(Convert.ToChar(2), Convert.ToChar(32)).Trim();
if (data.StartsWith("AX"))
{
string[] arrData = data.Split('\n');
this._barcodeScanner.StopAvailabilityThread();
Barcode code = new Barcode(arrData[0].Replace("\r", ""));
if (CheckIfBarcodeExists(code))
this.UpdateBarcodeNode(code);
else
this.CreateBarcodeNode(code);
BarcodeScannerCallbackEvent(sender, e, code);
this._barcodeScanner.StartAvailabilityThread();
}
this._barcodeScanner.ComDevicePluggedIn = ScannerDevice.ComAvailabilityState.Available;
}
if it doesnt answer anymore it will fire the "DeviceNotAvailableEvent()":
void BarcodeScannerDeviceNotAvailableEvent()
{
this._barcodeScanner.Close();
this._barcodeScanner.Dispose();
}
I have overriden the Dispose Event of the "SerialPort" class so that it´s going to abort the Thread:
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
this._deviceAvailableThread.Abort();
}
base.Dispose(isDisposing);
}
Serial ports date from the stone age of computing. That's where you plugged in your ASR-33 teletype to start typing in your Fortran program. The electrical interface is very simple. So is the Windows API to use a serial port from your own code. Practically any runtime environment supports them.
USB has replaced serial port hardware completely. It has a much more advanced logical interface to the machine, supporting many different type of devices. And it supports Plug and Play, allowing the operating system to detect when a device is attached or removed as well as automatically installing the device driver, etcetera.
This flexibility comes at a price however, a USB device always needs a device driver to become usable. Device drivers are not created equal. Different drivers require different ways to talk to the device. Usually done through DeviceIoControl() or Read/WriteFile() but those are very opaque API functions. In the early days of USB, device manufacturers would supply a DLL that provided a rich API to hide the implementation details.
That did not work so well, manufacturers are not very good at writing good APIs and they sure don't like to support them. So a good solution would be to support a standard API, one that's available on any machine, supported by any runtime, documented and maintained by somebody else. Like the serial port API.
That did not work so well, manufacturers are not very good at writing device drivers that emulate serial ports. The biggest hang-up with the API is that it doesn't have any support for Plug and Play. The core support for it is missing, after all serial port hardware doesn't have the logical interface to support it. There is some support for detecting that a device is attached through the DTR hardware handshake line, but no support whatsoever for detecting that the port is no longer there.
Detaching the USB device is the problem. In an ideal world, the emulator built into the device driver would simply pretend that the serial port is still there until the last handle on the device is closed. That would be the logical implementation, given that there's no way to trigger a Plug and Play event. For some strange reason that seems to be difficult to implement. Most USB drivers take the crummy shortcut, they simply make the device disappear even while it is in use.
This plays havoc on any user mode code that uses the device. Which is typically written to assume it is a real serial port and real serial ports don't suddenly disappear. At least not without drawing a bright blue spark. What goes wrong is pretty unpredictable because it depends on how the driver responds to requests on a device that's no longer there. An uncatchable exception in a worker thread started by SerialPort was a common mishap. Sounds like your driver really gets it wrong, it generates an error return code on the MJ_CLOSE driver request. Which is kind of a logical thing to do for a driver, after all the device isn't there anymore, but quite unsolvable from your end. You have a handle and you can't close it. That's up a creek with no paddle.
Every major release of .NET had a small patch to the SerialPort classes to try to minimize the misery a bit. But there's a limited amount that Microsoft can do, catching all errors and pretending they didn't happen ultimately leads to class that provides no good diagnostic anymore, even with a good driver.
So practical approaches are:
always use the Remove Hardware Safely tray icon in Windows
use the latest version of .NET
contact the vendor and ask for a driver update
ditch vendors that supply lousy drivers
tell your users that, just because it is the only thing you can do with a USB device, that unplugging it doesn't solve any problems
make closing the port easy and accessible in your UI
glue the USB connector to the port so it can't be removed
The 5th bullet is also what gets programmers in trouble. Writing serial port code isn't easy, it is heavily asynchronous and the threadpool thread that runs the DataReceived event is difficult to deal with. When you can't diagnose the software problem you tend to blame the hardware. There's very little you can do with the hardware but unplug it. Bad Idea. Now you have two problems.
This Problem Exists in .Net 2 , 3 , 3.5 you can use framework 4 (problem does not exist in .net 4)

How to see what port was opened by router

If I do the following:
UdpClient c = new UdpClient();
c.Connect(new System.Net.IPEndPoint(IPAddress.Parse("69.65.85.125"), 9900));
c.Send(new byte[] { 1,2,3,4,5 }, 5);
then I will be sending a packet to my router then my router will send that packet to the ip "69.65.85.125".
If I where to capture that packet on the computer that has the ip "69.65.85.125" I will be able to see the port that was oppened by the router (client.RemoteEndpoint). How will it be possible to see that information without capturing the packet at the other enpoint? Is there a way to query the router?
If your router supports it you can query it via UPnP. Here is a wrapper library for UPnP I found for .NET, I have never used it so I cant give you any advice if it is good or not.
Look at the ComponetsTest program for example code in the zip for the library. You will need to reference the UPnP documentation to find out what calls you will need to make to the service.
From the message board of the library of someone asking a how to find port mappings.
The WANPPPConnection and WANIPConnection services have actions called
GetSpecificPortMappingEntry, simply call this iterating through the
indexes from 0 until an error is returned, each call will return
another UPnP port mapping, you can also get the static mappings with a
different service.
In order to get the public IP, the remote device should respond by sending a UDP packet back to you that contains the IP address and port it saw. This is one of the most fundamental concepts behind a STUN server, commonly used in UDP hole-punching algorithms.
There are several free STUN servers available that do exactly this. Send one of them a "binding" request, and you will get back a response with your public IP address and port.
stun.l.google.com:19302
stun1.l.google.com:19302
stun2.l.google.com:19302
stun3.l.google.com:19302
stun4.l.google.com:19302
stun01.sipphone.com
stun.ekiga.net
stun.fwdnet.net
stun.ideasip.com
stun.iptel.org
stun.rixtelecom.se
stun.schlund.de
stunserver.org
stun.softjoys.com
stun.voiparound.com
stun.voipbuster.com
stun.voipstunt.com
stun.voxgratia.org
stun.xten.com
If you are truly interested in doing proper UDP hole-punching, check out ICE (Interactive Connectivity Establishment). It's a brilliant algorithm that uses STUN and another protocol called TURN to guarantee a successful connection between peers. (Apple uses it for Facetime video calls, among others.)
If you're interested, the company I work for has developed a product called IceLink that uses ICE/STUN/TURN to establish direct data streams between peers. SDKs are available for .NET, Mac, iOS, Android, Java, Windows Phone, Windows 8, Unity, Xamarin, and more, and it even includes full support for WebRTC audio/video streams.

32feet.net: How to connect to a specific COM port via BluetoothClient

I am trying to build a windows application with C#/Visual Studio 2010 which would do the following functions (in sequence): For bluetooth operations, I am using 32feet.Net library functions.
Find the bluetooth devices and list them in the list/combo box for the user to select. (I want to allow user to select multiple devices and hence NOT going for SelectBluetoothDeviceDialog class option.). I can get the list of devices via BluetoothClient.DiscoverDevices(), however, it is not an async operation. If possible, I would like to go for the async operation. I read about the BluetoothComponent class with events DiscoverDevicesProgress and DiscoverDevicesComplete and method DiscoverDevicesAsync but could not get it working. If possible, kindly share a sample code for this.
User selects the devices from the list and clicks 'Pair' button. So far I can successfully pair the devices via BluetoothSecurity.PairRequest. No issues here.
User now selects one/multiple device(s) from the 'paired' list and clicks 'connect'. Here I tried to connect to the device using BeginConnect (for async operation) and Connected methods of the BluetoothClient class but getting following exception.
System.Net.Sockets.SocketsException: {"An invalid argument was
supplied 000319002CC6:0000110100001000800000805f9b34fb"}.
The number in the above exception is GUID number required for the Connected method which I passed using BluetoothService.SerialPort. This will fail as my device is expecting to be connected at COM7 port. I am not sure how can I connect/pair a device at the specific COM port? Is is even possible by 32feet.Net library functions? If so, kindly provide a code sample.
References Note:I have already read and tried to implement the code explained in the article below on StackOverflow. However, due to my requirements (allowing user to pair and connect to multiple devices at COM ports) I am unable to run the same code. However, it did help understanding the concept.
32feet.net howto discover nearby bluetooth devices async in c#
Request you to advise the best way to handle this situation. In case I should try using any other library/functions other than 32feet.Net , do let me know.
My ultimate goal is to BOTH read and write data from and to the connected device(s). So, as of now, I am just trying to get connected on a specific COM port via bluetooth.
Regards,
Rumit
===========================
EDIT: updated information for answer 1:
I have received a bluetooh device (a patch) which is supposed to be connected to TOSHIBA VIRTUAL BT COM port. I apologize if the TOSHIBA information was necessary to better answer the question. I am new to the communication with ports. So far I know that I need to use COM7. I have an application built in C++ which connects to the same patch on COM7 via bluetooh. However, I don't have the source code and I have been asked to implement the same utility in C#. From your reply, can I assume that the C++ application might be using Windows Sockets 2 by any chance?
Also, I could see an option to specify a port (integer value) value in BluetoothEndClient but that also did not work. So, I assume that the port was not COM and was some other type of port.
Regards,
Rumit
Just briefly just now. You seem to be mostly on the right lines.
1) That error is presumably the one with name 'InvalidArgument' and code 10022 (check SocketException.SocketErrorCode).
So for the MSFT Bluetooth stack it has meaning (See http://32feet.codeplex.com/wikipage?title=Errors):
"Plug and Play, driver-stack event, or other error caused failure."
So that means that something is going wrong at the hardware level with the connection, either with the dongle itself or the pair of devices are mis-communicating. It's not a Parani module you are connecting to, is it?
Pair with it manually in the Bluetooth UI, then see if the connection works then.
2) Do you really want a COM port?
I very much prefer working with Sockets and System.IO.Streams. COM ports are hard to set-up, very hard to maintain, and hard to use. Only if you have a third-party program that only uses COM ports should you need to use them.
BluetoothClient doesn't create a COM port, it uses Sockets and returns a Stream to read and write to.
I have found a solution to successfully connect to a bluetooth device using WCL library as described below.
Step1: Make the wclClient's Transpport property to ctSerial.
client.Transport = wclClientTransport.ctSerial; //This makes the wclClient to listen to the COM ports.
Step2: Specify the COM port number by setting client.SerialParams.Port property. For Example,
client.SerialParams.Port = 5; // For COM5
Regards,
Rumit

c# ascii protocol problem

i have a program that send ASCII commands to a device via a serial port. The program is a demo and doesn't do what i want.
I am just trying to get the device to respond in c# and I'm not getting anything back.
all the serial port settings are correct.
I am sending exactly the same message as the demo software.
//e.g message <STX>ABC<EOT>
byte[] msg = new byte[5];
msg[0] = 0x02;
msg[1] = 0x41;
msg[2] = 0x42;
msg[3] = 0x43;
msg[4] = 0x04;
comport.write(msg, 0,msg.length)
the device is a monitor. The code was only an example. there isn't a heartbeat just a response for a correct message sent or a error message. the settings are standard 9600-8-N-1. "paperclip between pins 2 and 3 (TX and RX)." yeah i know the cable works because its the same one used with the product software that works. and im getting back what i send. I have used a virtual com program and everything seems alright. "6 bytes but initializing only the first 5. " sorry typo.
the SerialPort.DtrEnable and RtsEnable properties to true. are on by default in c#. i have tried the hyper terminal and am not getting a response with that either. I have sent \r and \n with no luck.
This C# Tutorial on Serial Port Communication should be able to help. I'm not sure if there is an appropriatei intrinsic caste between Hex and Byte through assignment in C#. That may be the source of your problem.
Device Heartbeat
Does the device send a DC2 or DLE response (heartbeat)? If so, try opening a COM port in Hyperterminal using basic 9600-8-N-1 settings and see if you get anything. Is there any STX, SYN, ETX commands sent back when you try to send a command? I'm not sure on the command-set implementation for the hardware you are trying to communicate with.
Checking COM Port Operation
Have you checked if your COM port is working properly? You can create a loopback by inserting a paperclip between pins 2 and 3 (TX and RX). This will loopback your COM port and in Hyper terminal you can open that COM port and type. The characters will echo back.
You can also use a piece of software called com0com to create virtual COM ports to test what you are sending before you actually send it.
It provides pairs of virtual COM ports that are linked via a nullmodem connetion. You can then use your favorite terminal application or whatever you like to send data to one COM port and recieve from the other one
Without anymore specific information, we'll be grasping at straws.
You're allocating and sending 6 bytes but initializing only the first 5.
Also, according to what you write, you're doing everything correctly, exactly as the demo program. Right? Then I can see only one solution: The device is pulling your leg!
Seriously: If one program works and your doesn't, there MUST be some difference.
By far the most common mistake is forgetting to turn on the hardware handshake signals. The device won't send anything if it thinks the host is turned off. Make sure you set the SerialPort.DtrEnable and RtsEnable properties to true.
As mentioned before, fix the array size. Although it probably won't help, the STX character ensures that junk is thrown away.
Check if basic hardware is okay with the Windows Hyperterminal applet. You can send the message you are trying to transmit by typing Ctrl+B, ABC, Ctrl+D
As others have suggested, it is good idea to check what is being sent and received with some kind of terminal software. I have had success with "realterm"-- it has nice displays of ascii or binary/hex views.
Since you are working with ASCII, another issue might be that you are not sending the correct line-terminating character. Some devices expect \r and others \n. Make sure you are setting that correctly.
the device is a monitor. The code was only an example.
there isn't a heartbeat just a response for a correct message sent or a error message.
the settings are standard 9600-8-N-1.
"paperclip between pins 2 and 3 (TX and RX)." yeah i know the cable works because its the same one used with the product software that works. and im getting back what i send. I have used a virtual com program and everything seems alright.
"6 bytes but initializing only the first 5. " sorry typo.
the SerialPort.DtrEnable and RtsEnable properties to true. are on by default in c#.
i have tried the hyper terminal and am not getting a response with that either.
I have sent \r and \n with no luck.

C# SerialPort - emulate pos keyboard

We are trying to emulate a POS keyboard in order to integrate an application with an existing Point of Sale application.
We ran across this software: Virtual Serial Port Kit
It basically creates a virtual serial port pair so that data send to COM1 can come out of COM4 and vice versa. This allows our application to send data through COM4 to appear to the POS application that it is talking to a keyboard on COM1.
Pretty ingenious, but it seems there is some kind of signalling going on that we are not able to replicate with the .Net System.IO.Ports.SerialPort class...
From what we can tell from serial port monitoring programs, this is how the startup sequence works:
8 byte Command sent to keyboard
Keyboard beeps
Some kind of signal is sent from the keyboard
Second 8 byte command is sent to keyboard, triggered by the signal
Keyboard replies with device and version information
When using our virtual serial port, we cannot figure out how to replicate the signal sent from the keyboard. We can see all data coming through properly, so we believe the settings on our SerialPort object are correct. Here is a snippet of our SerialPort settings:
_port.BaudRate= 9600;
_port.Parity = Parity.None;
_port.DataBits = 8;
_port.StopBits = StopBits.One;
_port.DtrEnable = true;
_port.RtsEnable = true;
We also noticed from using portmon we see a GET_MODEM_STATUS request that is what the POS application is waiting on before sending the second command.
Any ideas on how to diagnose this? Since we are using .NET this whole situation is a little more low level than we're used to.
UPDATE: I also want to note that we tried the SDK here: Franson Serial Tools but we could not even get data to go through when using this SDK.
UPDATE: We have thrown out using any kind of virtual serial port. We have gotten a cable to run from the POS PC to another and can see data coming across to emulate the keyboard. Now our problem is that we can't figure out how to signal that the keyboard is ready to recieve data as the top answer mentions. It appears that the POS application sends the command to beep an waits up to 3 seconds waiting for a signal. So it times out when talking to our application, but not when talking to the real keyboard
How can we do this with the SerialPort class? We already set DtrEnable and RtsEnable to true, do we need to set something else? Or do we have to use a lower level serial port p/invoke to accomplish this?
SOLUTION:
_port.RtsEnabled = false;
Thread.Sleep(1000);
_port.RtsEnabled = true;
This makes the POS application think the keyboard is plugged in, which makes sense. I'll mark the #1 answer as the answer since it greatly helped us find the solution.
EDITED to give more perspective from the point of view of simulating the keyboard.
As it happens I have written low-level drivers for the 92R keyboard in the distant past.
You really need the documentation for the proprietary protocol to do this properly - for example commands sent to the keyboard contain a sequence number and a checksum. I'd recommend contacting Fujitsu and attempting to get hold of this documentation.
From what you've described:
The first 8-byte command you sent was probably a reset command (as it caused the keyboard to beep). The keyboard sends a response to acknowledge the command, then resets itself.
After sending a reset command, the POS app needs to wait for the keyboard to reset (I think about 3000ms) before sending other commands.
It looks like the second send is a command to request the firmware version.
The POS app will also need to subsequently send a command to enable "autoinput" before the keyboard will actually send keystrokes.
There are also commands available to request the keylock position, sound the tone generator, enable/disable the MSR, and write to the optional embedded 2-line display. So your simulator will need to be capable of reproducing the responses to these commands.
Once the POS app has enabled "autoinput" the keyboard will send unsolicited messages with the keystrokes being pressed (or keylock position changes, or MSR input). IIRC these messages also have a sequence number and checksum that you will need to reproduce in your simulator.
The only signalling I know of is that the keyboard raises CTS when it is ready to receive data. If you connect two ports on a PC, you need a special null modem cable (see below) so that when your simulator raises RTS on COM4 it will be seen as CTS on the other port.
The COM ports on a TeamPOS motherboard provide power to the keyboard. You probably don't want to connect these pins to your COM4 port, so I would suggest using a null modem cable that connects only the following pins:
2 (Tx data) - 3 (Rx data)
3 (Rx data) - 2 (Tx data)
7 (RTS) - 8 (CTS)
8 (CTS) - 7 (RTS)
I've not done serial port development for years, but when I did I always used a Crossover Cable and a second PC running Windows HyperTerminal.

Categories

Resources