btframework how to pair & bond with encryption (Bluetooth LE noob question) - c#

I am having trouble trying to pair & bond a Bluetooth LE device using btframework (www.btframework.com), specifically the Nonin Wristox 3150 BLE
The documentation for the device states...
The 3150 BLE uses the Just Works
pairing method with bonding support. Upon successful pairing, the collector should initiate bonding, and the 3150 BLE will save the long term bonding key associated with the collector. The 3150 BLE requires the
collector to be bonded in order to encrypt the connection. When bonding is complete, the collector should
encrypt the connection.
I'm trying to work out what I should be doing to get connected. I've actually managed to get it connected once, which is how I've done all my development, but what I've done does not seem to have worked when I try it again. Using the BTFramework demo application, their "GattClient" - I can discover my device no problem, but when I click on "Connect", it connects to the device with a 0 error code (indicates success) , but the device disconnects a second later. I'm guessing this is because I haven't done all the pairing above.
So I've used their "Bluetooth Manager" to try pairing. I set the MITM to "ProtectionRequiredBonding", IOCap to "DisplayOnly" and BLE Protection to "Encryption", and click "Pair".
This actually worked once - I was paired, and then I was able to use the GattClient to Connect and get the services, characteristics and see the characteristic changes.
However I haven't been able to repeat the exercise. When I use Windows to remove the device, I'm back to the previous state where I can connect but get disconnected by the device, and I tried the above again. It doesn't seem to work now though. I usually get error 0x005105C (device not found) when I try to connect now. In the Window settings devices page, the status seems to change between "Connected" and "Paired" at random, and sometimes the device itself just starts reporting a connection error. (The device is not very forthcoming about what's causing the error). It always reports the pairing itself to be a success though
There is also this:
If the encryption process fails, it is likely that either the collector or 3150 BLE has deleted its bond key. When this occurs, the 3150 BLE will delete its bond key if present. It is recommended that the collector also delete its bond key if present.
Is this something I need to be doing? How is this done with btframework?

It appeared becasue your device has random MAC which changes each time you connect.disconnect.
So the correct sequence is:
Discover device.
Pair with it.
Connect.
Do what you need.
Disconnect.
Unpair (through your code, not through Windows device manager.)
If need connect to it once again go to step 1 so the device will be found with new MAC.
Should you have any questions it faster to get answered if you contact us by e-mail (support#btframework.com).

Just to follow up on this, it turned out to be a quirk specific to my device. It only allows pairing for the first 2 minutes after putting in you're batteries. If I remove the batteries and put them back in, I can pair with the device.

Related

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

PushSharp always return device expired

I'm trying to send a push notification using https://github.com/Redth/PushSharp
I'm using the sample project as is (having commented out the non ios stuff from program.cs), I confirmed that the app i'm using is the correct app, I've regenerated the developer push cert.
I'm running the app from xcode, so that it is devlopment providsioned..
The message seems to go fine, but then comes back
Waiting for Queue to Finish...
Sent: Apple -> {"aps":{"alert":"1 Alert Text!","badge":7,"sound":"default"}}
Queue Finished, press return to exit...
Device Subscription Expired: Apple -> [Device Id Removed]
I'm getting the device id from my app, to confirm it coumes out broken into Hex Octets, and i simply remove the spaces
So... not sure where to go from here, seems that apns is saying the app doesn't exist on my device, but it certainly does..
This is almost always due to a mismatch between the development and production provisioning profile certificates.
Check you're using the correct one... if this is still a problem!

SerialPort.GetPortNames() is wrong

If a detach a serial device which is still being used by windows, SerialPort.GetPortNames() will return that same detached device as actually still being attached. I also can't close the serial port without an unhandeled exception error stating that the port does not exist (which is true).
I can confirm that the device map for SERIALCOMM in the registry is not being updated either, which is where SerialPort.GetPortNames() gets the port names I presume. The hardware manager detects the right COMM ports.
Is there a way around this? Can I simply delete the SERIALCOMM registry entry?
I looked at this potential workaround, but I think that will just let me catch the exception.
I'm not an expert but my experience is that as long as you have any (SW-)object connected to the com-port it will be visible.
When I tested this some years ago I got the same result and not until I did lose my SerialPort object the port disappeared from the GetPortNames list (and presumable also the registry).
I think this is the way Windows handles this driver. If a serial port gets unplugged while in use in SW the system continues to have a place-holder for the serial port until it is released by SW.
In my SW I solved this by having a timeout for the function I needed (the other end could stop working as well) and before every new start of program-loop (normally once every 5min-1h) I just released the COM-port and reconnected to it, if reconnect failed the port was detected as lost...
Hope this helps you.

Connection between 2 computers via dial up modem without internet in 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.

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.

Categories

Resources