I am developing a Xamarin.iOS Bluetooth enabled app and i have some hurdles which i need to overcome. I am trying to make a connection from C# iOS app to peripheral device; I can connect successfully to the device but after discovering services and characteristics of the device, I need to catch particular service so that i can further use it for different purposes.
Now, the issue is how can i catch particular service from list of services in the cb peripheral object. Each service is identified by CBUUID object and i already know the CBUUID object that the device is returning, but i am not sure how can i compare them so that i know i catch the appropriate service.
If you are targeting iOS 7.1 (or later) then you can compare the System.String Uuid property of CFUUID. That's the easiest way. E.g.
if (cbuuid1.Uuid == cbuuid2.Uuid)
Console.WriteLine ("Equal");
else
Console.WriteLine ("Different");
Otherwise (iOS 7.0 and earlier) you'll need to compare the NSData Data properties of CFUUID. First compare their length and, if equal, compare each byte inside them. E.g.
bool equal = false;
using (var d1 = cbuuid1.Data)
using (var d2 = cbuuid2.Data) {
if (d1.Lenght == d2.Length) {
for (int i=0; i < d1.Lenght; i++) {
if (d1 [i] != d2 [i]) {
equal = false;
break;
}
}
}
}
Console.WriteLine (equal ? "Equal" : "Different");
Related
i am new to WIA. And i have been asked to make scaning service scan faster and duplex. My current service scan one page, then put it in pdf and so on untill there is less then 20 pages(this number just a crutch used before me, will be glad if someone explane how to get "if there is any paper in there" variable). I started to dig and found docs on MSDN describing properties and after found this post describing duplex sanning, but with mysterious 5 in set. After I found this and figured out what i need WIA_DPS_DOCUMENT_HANDLING_SELECT to set to 0x205(FEEDER + DUPLEX + AUTO_ADVANCE). So I tried to setup them like this:
private static void SetProperty(Property property, int value)
{
IProperty x = (IProperty)property;
Object val = value;
x.set_Value(ref val);
}
...some code...
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
SetProperty(prop, 517);
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
And it did't worked for me... It just stuck on setting... Can Somebody explain how to setup AUTO_ADVANCE and DUPLEX props? Or maybe "make scanning faster and duplex" need something more then just AUTO_ADVANCE and DUPLEX and my perception about them is wrong? Or I should considering "ISIS / TWAIN (Windows XP / Vista / 7 / 8 / 8.1 / 10)" string in my scan description and use other libraries?
(Window 10, Canon DR-M160||, DR-M160 & DR-M160II Driver for Windows)
and also here is the current fetch function:
public List<ImageFile> FetchImageList()
{
List<ImageFile> imageList = new List<ImageFile>();
//bool hasMorePages = true;
int testcount = 0;
while (testcount >= 0)
{
testcount--;
WIA.Device device = FindDevice(_deviceId);
if (device == null)
{
LOGGER.Warn("Scanner device not found");
return null;
}
// get item
WIA.Item scanItem = device.Items[1] as WIA.Item;
LOGGER.Debug($"ScanItem: {scanItem.ItemID}");
try
{
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
LOGGER.Warn("here");
SetProperty(prop, 517);
LOGGER.Warn("here");
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
// scan image
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Front");
//get back side
image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Back");
}
catch (Exception e)
{
throw (e);
}
}
return imageList;
}
Well... I tried to make duplex scan without AUTO_ADVANCE and got HRESULT: 0x8000FFFF (E_UNEXPECTED) on Transfer call. According to this post(even though that was on Windows 7) I guess there is no way to solve this for me by using WIA, still hope there will other suggestions...
Solved problem
I used saraff.twain and it worked for me:
- git page :https://github.com/saraff-9EB1047A4BEB4cef8506B29BA325BD5A/Saraff.Twain.NET
good library with grate wiki page.(Also have similar library for .net 4.6.1)
I am currently trying use 32feet.net to connect to a bluetooth speaker that once shutdown (the computer or the speaker) they stay paired but they dont auto reconnect. Therefore I want to make an windows service that tries to reconnect to it every so often if its not connected and if it can find it.
I have tried
C# 32feet.Net: Handling two bluetooth connections in seperate threads, gives SocketException
Code but for some reason there is a few things that light up red.
I am also trying to figure out and make this code work at the same time for the same purpose
public void btconnect()
{
List<Device> devices = new List<Device>();
InTheHand.Net.Sockets.BluetoothClient bc = new InTheHand.Net.Sockets.BluetoothClient();
InTheHand.Net.Sockets.BluetoothDeviceInfo[] array = bc.DiscoverDevices();
int count = array.Length;
for (int i = 0; i<count; i++)
{
Device device = new Device(array[i]);
devices.Add(device);
}
foreach(Device d in devices)
{
if (d.DeviceInfo.ToString().Equals("myphonesdevicenumber"))
{
Guid MyServiceUuid
= new Guid("{00112233-4455-6677-8899-aabbccddeeff}"); // found this somewhere not sure what the string represents.
byte[] guidbytearray = d.DeviceInfo.ToByteArray(); // guid as a byte array.
string guidstring = d.DeviceInfo.ToString(); //guid as a string.
Int64 guid64 = d.DeviceInfo.ToInt64(); // guid as an int64.
Guid g = new Guid(guidbytearray);
bc.Connect(d.DeviceInfo,MyServiceUuid);
// turnoff = false;
}
}
}
List devices = new List();
in the orignal code this wasnt there and I dont know if he was using (Device) it from a external reference or not.
In the article of 32feet, they list an inner-class named Device. You should use it in your program.
The Guid is the identifier for the socket used to connect to your BT device.
The format is a 32 digit long of hex numbers divided into group of 8, 4 ,4 ,4 and 12. Between the groups there is a '-'.
When running this program I keep receiving the error:
An unhandled exception of type 'System.Security.SecurityException' occured
Additional Information: ECall methods must be packaged into a system module.
class Program{
public static void Main()
{
Brekel_ProBody2_TCP_Streamer s = new Brekel_ProBody2_TCP_Streamer();
s.Start();
s.Update();
s.OnDisable();
}
}
How can I fix this?
The important part of the Brekel library is as follows:
//======================================
// Connect to Brekel TCP network socket
//======================================
private bool Connect()
{
// try to connect to the Brekel Kinect Pro Body TCP network streaming port
try
{
// instantiate new TcpClient
client = new TcpClient(host, port);
// Start an asynchronous read invoking DoRead to avoid lagging the user interface.
client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(FetchFrame), null);
Debug.Log("Connected to Brekel Kinect Pro Body v2");
return true;
}
catch (Exception ex)
{
Debug.Log("Error, can't connect to Brekel Kinect Pro Body v2!" + ex.ToString());
return false;
}
}
//===========================================
// Disconnect from Brekel TCP network socket
//===========================================
private void Disconnect()
{
if (client != null)
client.Close();
Debug.Log("Disconnected from Brekel Kinect Pro Body v2");
}
public void Update()
{
// only update if connected and currently not updating the data
if (isConnected && !readingFromNetwork)
{
// find body closest to the sensor
closest_skeleton_ID = -1;
closest_skeleton_distance = 9999999f;
for (int bodyID = 0; bodyID < skeletons.GetLength(0); bodyID++)
{
if (!skeletons[bodyID].isTracked)
continue;
if (skeletons[bodyID].joints[(int)brekelJoint.waist].position_local.z < closest_skeleton_distance)
{
closest_skeleton_ID = bodyID;
closest_skeleton_distance = skeletons[bodyID].joints[(int)brekelJoint.waist].position_local.z;
}
}
// apply to transforms (cannot be done in FetchFrame, only in Update thread)
for (int bodyID = 0; bodyID < skeletons.GetLength(0); bodyID++)
{
for (int jointID = 0; jointID < skeletons[bodyID].joints.GetLength(0); jointID++)
{
// only apply if transform is defined
if (skeletons[bodyID].joints[jointID].transform != null)
{
// apply position only for waist joint
if (jointID == (int)brekelJoint.waist)
skeletons[bodyID].joints[jointID].transform.localPosition = skeletons[bodyID].joints[jointID].position_local;
// always apply rotation
skeletons[bodyID].joints[jointID].transform.localRotation = skeletons[bodyID].joints[jointID].rotation_local;
}
}
}
It appears you are using a Unity library but trying to run it as a standalone application?
This error means you are calling a method that is implemented within the Unity engine. You can only use the library from within Unity.
If you want to use it standalone, you'll need to compile the library without referencing any Unity libraries, which probably means you'll need to provide implementations for anything the library is using (such as MonoBehaviour
http://forum.unity3d.com/threads/c-error-ecall-methods-must-be-packaged-into-a-system-module.199361/
http://forum.unity3d.com/threads/security-exception-ecall-methods-must-be-packaged-into-a-system-module.98230/
Additionally,
If your only problem is Debug.Log() throwing an exception, you could use reflection to plant your own Logger instance instead of Unity's one.
Step 1: Create "MyLogHandler" that will do your actual logging(write to file or to console or do nothing). Your class needs to implement "ILogHandler" interface.
Step 2: Replace unity default one with new one.
var newLogger = new Logger(new MyLogHandler());
var fieldInfo = typeof(Debug).GetField("s_Logger", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
fieldInfo.SetValue(null, newLogger);
Note: Keep in mind that reflection accesses field by name and if Unity decide to change it in future, you will not get compile error - exception will be thrown in run-time.
I know this is old, but I came across a way to unit test Unity assemblies from within Visual Studio just by toggling a symbol definition from the Unity build settings. As long as you're OK with only being either able to either run tests or have the testable components usable in unity at one time, you can toggle unit testing mode and unity mode like this (images follow):
Make your unity component a partial class. Have one file where you declare that the partial class extends MonoBehaviour and put any stuff that has to actually use unity assemblies in there. This will not be tested by the unit tests but everything else will.
Use conditional compilation to make that file's contents only compile when a specific symbol is defined during the build. I used UNIT_TEST_NO_UNITY_INTEGRATION in my case.
When you want to run the unit tests from Visual Studio, update the build settings to define that symbol. This will exclude the Unity specific stuff from step 1 from the build and allow Visual Studio to be able to run your unit tests.
When you are finished testing, edit the build settings again and remove that symbol definition. Now your unit tests won't be able to run but your assemblies will work within Unity again.
I've been crawling in the web for about 5 hours now and couldn't find a solution for my problem:
My company is developing an educational game and I'm writing an autoupdater for it using Monotorrent. The game will be used in schools, but because most schools only have very weak internet connections there should only be one computer in the network that downloads from a httpseeder, and the others should leech from the one computer that is downloading from the httpseed.
So I get loads of IP-addresses from the tracker and need to filter out only the ones that are in the LAN.
Of course schools are sometimes quite strict with firewalls and there will be loads of routers and switches between some computers in a school.
I've already tried most solutions, things like
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface iface in interfaces)
{
IPInterfaceProperties properties = iface.GetIPProperties();
foreach (UnicastIPAddressInformation address in properties.UnicastAddresses)
{
Console.WriteLine(
"{0} (Mask: {1})",
address.Address,
address.IPv4Mask
);
}
}
Or similar techniques only deliver the information of the router/switch/whatever.
So in a nutshell, what I want to do is check if a given IP is accessible via LAN.
I'd really appreciate any help because this feature is the last one remaining :)
You could take advantage of TTL. With a TTL of 1 the packet won't be able to make it to the internet:
private static bool IsLanIP(IPAddress address)
{
var ping = new Ping();
var rep = ping.Send(address, 100, new byte[] { 1 }, new PingOptions()
{
DontFragment = true,
Ttl = 1
});
return rep.Status != IPStatus.TtlExpired && rep.Status != IPStatus.TimedOut && rep.Status != IPStatus.TimeExceeded;
}
However, remember that it is called an IPv4 mask for a reason - you can use it as one (so here is your algorithmic solution):
private static bool IsLanIP(IPAddress address)
{
var interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (var iface in interfaces)
{
var properties = iface.GetIPProperties();
foreach (var ifAddr in properties.UnicastAddresses)
{
if (ifAddr.IPv4Mask != null &&
ifAddr.Address.AddressFamily == AddressFamily.InterNetwork &&
CheckMask(ifAddr.Address, ifAddr.IPv4Mask, address))
return true;
}
}
return false;
}
private static bool CheckMask(IPAddress address, IPAddress mask, IPAddress target)
{
if (mask == null)
return false;
var ba = address.GetAddressBytes();
var bm = mask.GetAddressBytes();
var bb = target.GetAddressBytes();
if (ba.Length != bm.Length || bm.Length != bb.Length)
return false;
for (var i = 0; i < ba.Length; i++)
{
int m = bm[i];
int a = ba[i] & m;
int b = bb[i] & m;
if (a != b)
return false;
}
return true;
}
Typically any IPs like 10.x.x.x (Class A) or 192.x.x.x (Class C) can be safely assumed to be inside a private local area network. IP Classications
One thing that you could possibly use is to try and communicate between clients using multicast. Most firewalls and routers would block multicast traffic (and ISPs most definitely), meaning that you wouldn't be able to join a multicast group if no other client is on the lan. A dumb switch would pass on the traffic, a layer 3-switch might block it, or could allow it depending on configuration. Either way, if the layer 3 switch block it, you are probably on different subnets altogether anyway so all other options would fail as well.
One technology that comes to mind is SSDP ( http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol ) which would serve your purpose pretty good I believe. That way you don't really need to figure out if you are on a LAN or not, just search for another node that is actively downloading, if you can't find one, start downloading yourself.
Since SSDP is a standard used in uPnP you would probably be able to find decent implementations you could work with.
I'm working on a mobile application (C#/WPF on a tablet PC) that prints to a bluetooth connected printer. Right now I just fire off a print job, and if the printer is not present the printer subsystem reports an error to the user. I'm not doing anything programatically with Bluetooth, just using PrintDialog().
I'd like to modify this process to detect the printer first - if it is not available, then I'll just store the document without printing. Is there a way in code for me to detect if the bluetooth device is connected/active/available?
If I look at the device in the Bluetooth panel under Control Panel, it doesn't seem to have any sort of status that reflects whether or not the device is available, so maybe this isn't possible.
I'm assuming the printer has already been setup and configured in Windows - all I need to do is detect if it is actually present at a given point in time.
Perhaps use the 32feet.NET library (of which I am the maintainer) and check if the printer is present before submitting the job. You'd need to know the Bluetooth address of the printer; can one get that from the system, or maybe you always know it.
Discovery on the MSFT Bluetooth stack always returns all known devices in amongst those in range :-( but we can use other means to detect the device's presence/absence. Perhaps using BluetoothDeviceInfo.GetServiceRecords in its BeginGetServiceRecords form. e.g. something like (not tested/compiled):
bool IsPresent(BluetoothAddress addr) // address from config somehow
{
BluetoothDeviceInfo bdi = new BluetoothDeviceInfo(addr);
if (bdi.Connected) {
return true;
}
Guid arbitraryClass = BluetoothService.Headset;
AsyncResult<bool> ourAr = new AsyncResult<bool>(); // Jeffrey Richter's impl
IAsyncResult ar = bdi.BeginGetService(arbitraryClass, IsPresent_GsrCallback, ourAr);
bool signalled = ourAr.AsyncWaitHandle.WaitOne(Timeout);
if (!signalled) {
return false; // Taken too long, so not in range
} else {
return ourAr.Result;
}
}
void IsPresent_GsrCallback(IAsyncResult ar)
{
AsyncResult<bool> ourAr = (AsyncResult<bool>)ar.AsyncState;
const bool IsInRange = true;
const bool completedSyncFalse = true;
try {
bdi.EndGetServiceResult(ar);
ourAr.SetAsCompleted(IsInRange, completedSyncFalse);
} catch {
// If this returns quickly, then it is in range and
// if slowly then out of range but caller will have
// moved on by then... So set true in both cases...
// TODO check what error codes we get here. SocketException(10108) iirc
ourAr.SetAsCompleted(IsInrange, completedSyncFalse);
}
}