I need help in creating a C# script that set a android WiFi in hotspot mode. Here is the code that I managed to create.
public bool setAPEnabled(bool enabled)
{
using (AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"))
{
try
{
if(isWifiEnabled()==true){
setWifiEnabled(false);
}
using (var wifiManager = activity.Call<AndroidJavaObject>("getSystemService", "wifi"))
{
return wifiManager.Call<bool>("setWifiApEnabled",null, enabled);
}
}
catch (Exception e)
{
}
}
return false;
}
Everything works well - but I have a problem with setting the SSID and password. After reviewing the documentation I know that I have to replace my null value with the settings object, but I completely don't know how to do it in Unity.
Theses methods works only for android 5.0 and less !
The EASY way :
Try instantiating the WifiConfiguration first :
AndroidJavaObject wifiConfiguration = new AndroidJavaClass("android.net.wifi.WifiConfiguration");
Now you can call methods and set/get fields within this object :
// to set SSID
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
After settings all of the required fields just call your setWifiApEnabled method :
wifiManager.Call<bool>("setWifiApEnabled", wifiConfiguration, enabled);
Maybe you will have to set more fields than these two but to confirm that you should check the source and ensure what setWifiApEnabled method does internaly.
The HARD way :
( using reflection code )
Step 6 does not work for android 5.0+ !
Using reflection with AndroidJavaObject can be a bit tricky because you have to remember to dispose every object.
So from the beginning :
// android code for that should look like :
// wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
// but in Unity C# you have to split this into few chunks:
// 1. Get calling class :
using ( AndroidJavaObject classObj = wifiManager.Call<AndroidJavaObject>("getClass") )
{
// classObj should contains your class object
// 2. call get WifiConfiguration class details :
using ( AndroidJavaObject wifiConfiguration = new AndroidJavaObject("setWifiApEnabled") )
{
// 3. Fill that object :
wifiConfiguration.Set("SSID", meSSID); // string
wifiConfiguration.Set("preSharedKey", mePassword); // string
// 4. Get WifiConfiguration class definition
using (AndroidJavaObject wifiCfgClass = wifiConfiguration.Call<AndroidJavaObject>("getClass") )
{
// 5. Get boolean definition
using ( AndroidJavaObject booleanObj = new AndroidJavaObject("java.lang.Boolean") )
{
using ( AndroidJavaObject booleanClass = booleanObj.Call<AndroidJavaObject>("getClass") )
// 6. Get method definition
using ( AndroidJavaObject methodObj = classObj.Call<AndroidJavaObject>("getMethod", "setWifiApEnabled", wifiCfgClass , booleanClass))
{
// 7. Call that method :)
methodObj.Call("invoke", wifiManager, wifiConfiguration, enabled);
}
}
}
}
}
WifiConfiguration :
I was trying to find out why the above code might not work but for me it was working okay ( tested on some virtual machines and Samsung Galaxy S5 Neo ).
What may be the case ( which I found out at almost midnight ) is a passphrase.
According to this wikipedia article in the section about WPA-PSK
Also referred to as WPA-PSK (pre-shared key) mode, this is designed for home and small office networks and doesn't require an authentication server.[9] Each wireless network device encrypts the network traffic using a 256 bit key. This key may be entered either as a string of 64 hexadecimal digits, or as a passphrase of 8 to 63 printable ASCII characters.[10] If ASCII characters are used, the 256 bit key is calculated by applying the PBKDF2 key derivation function to the passphrase, using the SSID as the salt and 4096 iterations of HMAC-SHA1.[11] WPA-Personal mode is available with both WPA and WPA2.)
My suggestion would be to use the same passphrase as in the article linked above to make sure it's valid.
Also another thing to note is the SSID part which has a short but good description here on wikipedia.
A common, albeit incorrect assumption, is that an SSID is a string of human-readable characters (such as ASCII), terminated by a NUL character (as in a C-string). SSIDs must be treated and handled as what they are, a sequence of 0–32 octets, some of which may not be human-readable
From what I've checked you do not need to null-terminate your string within Java or C# because it will be handled by native code but still you should not exceed 31 characters ( 32 will be the null character ).
I checked this with :
SSID:MeHotSpot
WPA-PSK:5260305714217573
Related
I have a signature created using metamask and the personal_sign RPC method.
Now I want to verify this signature in my C# backend.
In order to do so I have found the Nethereum library.
I have written the below code trying to verify the signature (for now I have used 'test' as the signed message).
public void VerifySignature(string signatureString, string originalMessage)
{
string msg = "\x19Ethereum Signed Message:\n" + originalMessage.Length + originalMessage;
byte[] msgHash = new Sha3Keccack().CalculateHash(Encoding.UTF8.GetBytes(msg));
EthECDSASignature signature = MessageSigner.ExtractEcdsaSignature(signatureString);
EthECKey key = EthECKey.RecoverFromSignature(signature, msgHash);
bool isValid = key.Verify(msgHash, signature);
}
Now the isValid comes back as true. However, if I use key.GetPublicAddress() this address is different than my own public address, so I assume I'm doing something wrong. Can anyone explain to me what, or correct if I'm wrong?
NOTE:
If instead of
EthECKey testKey = EthECKey.RecoverFromSignature(signature, msgHash);
I use
EthECKey testKey = EthECKey.RecoverFromSignature(signature, msgHash, new BigInteger(1));
(I'm using the main network to sign which is chain 1)
I get an error saying "recId should be positive", not sure if this is related but I thought it's worth mentioning.
UPDATE:
Managed to fix this by changing the msg string to use "\x19" + "Ethereum ..." instead of "\x19Ethereum ...", \x19E results in a different character, and results in a different message hash.
The Ethereum address and the public key are different. The Ethereum address is the last 20 bytes of the hash of the public key (see https://ethereum.org/en/developers/docs/accounts/ and https://github.com/Nethereum/Nethereum/blob/master/src/Nethereum.Signer/EthECKey.cs#L201).
Greeting,
We have some translation stored in a resx file which contains a break line similar to:
"This is a Test
& or something similar. "
There are ~50 devs in our project and from time to time Visual studio corrects the translation into
"This is a Test
& or something similar. " causing our pipeline to fail (long story)
Now my goal is to write a test and to ensure that the translations are not "corrupted", but I found no way to get the actual hex or ASCII value of the string above.
It always comes as \n\r .
I also want to mention that I would like not to change the current behavior of the app, only to get the proper ASCII or hex from the resource
This is what I would like to get from the resx file using: GetString or similar
&# xA;&# xD;
&# 13;&# 10;
[TestMethod]
public void Test()
{
// Arrange
var x = ToLiteral("This is a Test
&& or something similar.");
// Act
var xExpected = ToLiteral(Resources.Something.Some_Title);
// Assert
x.ShouldBe(xExpected );
}
private static string ToLiteral(string valueTextForCompiler)
{
return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(valueTextForCompiler, false);
}
I am researching for a Barcode scanning application with iOS iPhone Camera.
I can use Swift to get the string data that I actually need from the image I scan. However, when using Xamarin with the Xamarin implementation of the AVFoundation.AVMetadataObject and AVMetadataMachineReadableCodeObject, I don't get all of the characters. The C# code appears to execute in the same way as the Swift code with two different results.
Example Xcode Swift:
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
found(code: stringValue)
}
will render something like this: WHICH I WANT
[)>\u{1e}06\u{1d}1SMYDATA\u{1d}S1MYDATA\u{1d}1PMYDATA\u{1d}WMYDATA\u{1d}4LUS\u{1e}\u{4}
Example Xamarin Foundation Code:
var barcodeMetadataObject = transformedMetadataObject as AVMetadataMachineReadableCodeObject;
if (barcodeMetadataObject != null)
{
var barcodeOverlayPath = this.BarcodeOverlayPathWithCorners(barcodeMetadataObject.Corners);
metadataObjectOverlayLayer.Path = barcodeOverlayPath;
// If the metadata object has a string value, display it.
string textLayerString = null;
if (!string.IsNullOrEmpty(barcodeMetadataObject.StringValue))
{
textLayerString = barcodeMetadataObject.StringValue;
}
else
{
// TODO: add Descriptor (line 618 in original iOS sample)
}
will render something like this: WHICH I DO NOT WANT...I WANT THE ENTIRE CHARACTER SET
[)>061SMYDATAS1911500531PMYDATAWMYDATA
So I have this: (Xcode)
[)>\u{1e}06\u{1d}1SMYDATA\u{1d}S1MYDATA\u{1d}1PMYDATA\u{1d}WMYDATA\u{1d}4LUS\u{1e}\u{4}
Versus this:(Xamarin)
[)>061SMYDATAS1911500531PMYDATAWMYDATA
I am not understanding why the implementation in Xamarin would not be supplying all of the same characters of the scan when it essentially acts only as a wrapper.
Does anyone have any idea?
I'm trying to send/receive a string through C#, in C# i just do:
SerialPort.WriteLine("A6");
but in CCS, if i try sending a string char after char it does not work at all, neither with ReadLine nor with ReadExisting! This is what i have tried creating an array, so that everytime we enter the RXBUFF pragma, we add the received char to the array, until the array is full (i randomly defined the array size to be 2, which means we deal with 2-char-length strings), and eventually send the string by sending char after char:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
if(__even_in_range(UCA1IV,18) == 0x02){ // Vector 2 - RXIFG
if(counter==0)
{
Data[0]=UCA1RXBUF;
counter++;
}
else
{
Data[1]=UCA1RXBUF;
counter=0;
UCA1TXBUF=Data[0];
while(!(UCA1IFG & UCTXIFG)); // until UCTXBUF1 is empty
UCA1TXBUF=Data[1];
}
}
in C#:
listBox2.Items.Add(SerialPort.ReadExisting());
i get non-sense text, like : ??A??? sometimes : ????A? etc.., but with:
listBox2.Items.Add(SerialPort.ReadLine());
in the first time i press the Send button which sends the "A6", i get nothing, the second time i get non-sense aswell , just like the ReadExisting behavior.
by the way, even if i try to send the string in the easiest way (without array and conditions), i mean like this:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
UCA1TXBUF='A';
while(!(UCA1IFG & UCTXIFG)); // until UCTXBUF1 is empty
UCA1TXBUF='6';
i also get inconsistent items in the listbox.
However, if i do this:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
UCA1TXBUF=UCA1RXBUF;
i do get "A6" in the listbox and everything just work fine (with ReadLine and ReadExisting)!
could anyone just tell me why this is happening?
I'v just neutralized the Parity bit, everything works now, Thank you all!
This indicates that you shouldn't be waiting for the TX flag inside the RX ISR. The RX interrupt routine should simply fill a FIFO buffer (a byte queue), so that you can parse its contents somewhere else (main routine?), and then create a response when needed.
Pseudo code for the RX ISR should be something like:
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
FIFO_Enqueue(&RxBuffer, UCA1RXBUF);
And somewhere inside the main() loop you can parse its contents:
while (1)
{
// find the first occurrence of "A6" and dequeue it
if (FIFO_StartsWith(&RxBuffer, "A6")
SendResponse();
}
I am learning programming in windows 8 with c#. I have worked through many tutorials (such as http://msdn.microsoft.com/en-us/library/windows/apps/hh986968.aspx) in the process and I am attempting to create a simple app showing data storage. All of the examples I have been able to find store only simple strings in roaming storage. Is there a way to store more complex data there?
example: a List of a basic class Person with a name and age. I attempted to do it as:
Saving the data:
roamingSettings.Values["peopleList"] = people;
Loading the Data:
people = (List)roamingSettings.Values["peopleList"];
WinRT information: Error trying to serialize the value to be written to the application data store.
when saving the data I get the error "Data of this type is not supported"
So, maybe all you can save is string values -- but I have not seen that specified anywhere either.
Yes, you can save your values to raoming data as a collection. The solution for your problem is
ApplicationDataCompositeValue class
See http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdatacompositevalue.aspx for more information
As you mentioned, You are developing in C# , following is the code for your problem
I imagined, you have a Person class with two members
class person
{
int PersonID;
string PersonName
}
Now, to read and write values for this class, here is the code
First in the constructor of your Window class, under the InitializeComponent();, create an object of roaming settings
Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
To Write to a composition, use the following code
void write (Person Peopleobj)
{
Windows.Storage.ApplicationDataCompositeValue composite = new Windows.Storage.ApplicationDataCompositeValue();
composite["PersonID"] = Peopleobj.PersonID;
composite["PersonName"] = Peopleobj.PersonName;
roamingSettings.Values["classperson"] = composite;
}
To Read a Person object, use the following code
void DisplayOutput()
{
ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)roamingSettings.Values["classperson"];
if (composite == null)
{
// "Composite Setting: <empty>";
}
else
{
Peopleobj.PersonID = composite["PersonID"] ;
Peopleobj.PersonName = composite["PersonName"];
}
}