USB hosting with UsbSerialForAndroid won't receive serial data - usb

I'm using an OTG cable to allow my 'moto-e6 play' (Android version 9) to be a USB host to an AdaFruit Trinket M0. Off the shelf, the Trinket repeatedly sends a serial text string as soon as it powers up, and I've verified it does that when I connect Putty to it from my Windows PC. On my phone I have code using a Xamarin port of UsbSerialForAndroid. The code successfully finds the device and opens the port, but I see no serial data coming from the device. Specifically, the UsbDeviceConnection.RequestWait within the UsbSerialPort.Read method blocks forever. If I replace the RequestWait with a 1-second Sleep, there's nothing in the buffer. I've also tried all the different protocols that UsbSerialForAndroid supports (CdcAcmSerialDriver, etc.) to no avail. Also, the phone registers the Trinket as a keyboard, but I assume that still allows other code to access it, as well. Does anyone know what the problem is or what I might try to get serial working? Here's the simplified (Xamarin) code without error checking:
usbManager = GetSystemService(Context.UsbService) as UsbManager;
var usbDevice = usbManager.DeviceList.ToList()[0].Value;
if (!usbManager.HasPermission(usbDevice))
usbManager.RequestPermission(usbDevice, null);
var table = UsbSerialProber.DefaultProbeTable;
var type = typeof(Hoho.Android.UsbSerial.Driver.CdcAcmSerialDriver);
table.AddProduct(0x239A, 0x801F, type);
var prober = new UsbSerialProber(table);
var drivers = prober.FindAllDrivers(usbManager);
var driver = drivers[0];
UsbDeviceConnection connection = usbManager.OpenDevice(driver.GetDevice());
var ports = driver.GetPorts(); // Most devices have just one port (port 0)
var port = ports[0]; // Most devices have just one port (port 0)
port.Open(connection);
// The following serial params are the same as I successfully used with Putty on Windows
port.SetParameters(9600, 8, Hoho.Android.UsbSerial.Driver.StopBits.One, UsbSerialPort.PARITY_NONE);
var bytes = new byte[32];
var len = port.Read(bytes, 32); // <-- this hangs at the RequestWait call

Related

send mail using MailKit without specifying port number

Using asp.net core 3.1
I can send email using this code:
Code snippet 1 using System.Net.Mail.SmtpClient
using (System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient())
{
smtp.Host = "mail.my-real-domain-name.com";
smtp.EnableSsl = false;
NetworkCredential credential = new NetworkCredential(emailModel.From,
emailModel.Password);
smtp.UseDefaultCredentials = false;
smtp.Credentials = credential;
smtp.Send(mm);
}
but when I try to send email using MailKit it doesn't connect to mailserver
Code snippet 2 in MailKit documentation
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
client.Connect("mail.my-real-domain-name.com",0,false);
client.Authenticate(emailModel.From, emailModel.Password);
client.Send(message);
client.Disconnect(true);
}
What's the equal of Code snippet 1 using MailKit?
None of below lines worked so I want to know how to send email without specifying port number using MailKit.
It doesn't throw any error, just doesn't connect, I mean it stays in client.Connect line.
// client.Connect("mail.my-real-domain-name.com", 465);
// client.Connect("mail.my-real-domain-name.com", 465, true);
// client.Connect("mail.my-real-domain-name.com", 25, false);
// client.Connect("mail.my-real-domain-name.com", 2525, false);
// client.Connect("mail.my-real-domain-name.com", 587,MailKit.Security.SecureSocketOptions.StartTls);
MailKit
If you take a look at the SmtpClient.cs reference source, in the Initialize() method:
if port == 0
if there is a MailConfiguration XML file available, it uses the specified port from the XML (which defaults to port 25): https://referencesource.microsoft.com/#System/net/System/Net/Configuration/SmtpNetworkElement.cs,e4c99455ef3ea37c
else if there is no XML config file, it uses the static defaultPort member, which is set to 25.
So to get the same behavior as System.Net.Mail, use port 25.
MailKit will also accept port = 0 in the Connect() call and, depending on what the SecureSocketOptions argument is, it will choose an appropriate default port in the ComputeDefaultValues() method: https://github.com/jstedfast/MailKit/blob/master/MailKit/Net/Smtp/SmtpClient.cs#L1253
If the port == 0, then if useSsl=true or socketOptions=SslOnConnect, it will choose port 465, otherwise it will choose port 25.

How to connect to database with SSL in google apps script?

I'm trying to connect to a database via SSL within Google Apps Script, referencing these docs. The error is:
Execution failed: Failed to establish a database connection. Check connection string, username and password.
I can use these exact same parameters from another db client (Sequel Pro) and it works fine. I've got the db accepting connections from any IP address (0.0.0.0/0).
I believe I've eliminated all the other variables (user name, password, etc. etc.), its only when I attempt to use SSL within Apps Script that it fails.
Can anyone provide a working example of connecting to a MySQL database with SSL within Google Apps Script?
My apps script:
function connectDb() {
var address = 'x.x.x.x'; // no, I'm not literally using x's in my ip address
var instanceUrl = 'jdbc:mysql://' + address + ':3306/';
var clientSslKey = '-----BEGIN RSA PRIVATE KEY-----\n' +
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n' +
/* snip */
'-----END RSA PRIVATE KEY-----';
var clientSslCertificate = '-----BEGIN CERTIFICATE-----\n' +
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n' +
/* snip */
'-----END CERTIFICATE-----';
var serverSslCertificate = '-----BEGIN CERTIFICATE-----\n' +
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n' +
/* snip */
'-----END CERTIFICATE-----';
// https://developers.google.com/apps-script/reference/jdbc/jdbc#getconnectionurl-info
var connParams = {
user: 'temp',
// no password set
_serverSslCertificate: serverSslCertificate,
_clientSslCertificate: clientSslCertificate,
_clientSslKey: clientSslKey,
};
var conn = Jdbc.getConnection(instanceUrl, connParams);
}
EDIT
I filed a bug here which got marked as a duplicate of this other one which as a "P2" priority. Maybe that means it will be fixed soonish?
I can confirm that I can connect to a MySQL database with SSL within Google Apps Script.
It's important to note useSSL=true is indeed necessary
I was able to get it working by following the example at https://issuetracker.google.com/issues/36761592#comment18 (relevant snippet repeated below):
var conn = Jdbc.getConnection('jdbc:mysql://<ip address>/<db name>?useSSL=true', {
user: '<user>',
password: '<pass>',
_serverSslCertificate: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
_clientSslCertificate: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
_clientSslKey: '-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----'
});
If you're using a Google Cloud SQL instance, you may want to consider using getCloudSqlConnection(). Presumably it's encrypted as well (based on the fact that I can indeed get a connection when the corresponding instance has "Only secured connections are allowed to connect to this instance." enabled), and, importantly, doesn't require you to manage (i.e. not lose control of) the key and certs yourself.

Can I use the same WebRTC channel for audio/video and file transfer?

I am a newbie to WebRTC. I am building an application that enables users to view each other's video stream, as well as exchange files. The audio/video part is implemented and working. The problem is I need to add the ability to exchange files now. I am using the below code to initialize the PeerConnection object
var connection = _getConnection(partnerId);
console.log("Initiate offer")
// Add our audio/video stream
connection.addStream(stream);
// Send an offer for a connection
connection.createOffer(function (desc) { _createOfferSuccess(connection, partnerId, desc) }, function (error) { console.log('Error creating session description: ' + error); });
_getConnection creates a new RTCPeerConnection object using
var connection = new RTCPeerConnection(iceconfig);
i.e., with no explicit constraints. It also initializes the different event handlers on it. Right after this, I attach the audio/video stream to this connection. I also cache these connections using the partner id, so I can use it later.
The question is, can I later recall the connection object from the cache, add a data channel to it using something like
connection.createDataChannel("DataChannel", dataChannelOptions);
And use it to share files, or do I have to create a new RTCPeerConnection object and attach the data channel to it?
You certainly do not have to create a another PeerConnection for file transfer alone. Existing PeerConnection can utilize RTCDatachannel with behaves like traditional websocket mechanism ( ie 2 way communication without a central server )
`var PC = new RTCPeerConnection();
//specifying options for my datachannel
var dataChannelOptions = {
ordered: false, // unguaranted sequence
maxRetransmitTime: 2000, // 2000 miliseconds is the maximum time to try and retrsanmit failed messages
maxRetransmits : 5 // 5 is the number of times to try to retransmit failed messages , other options are negotiated , id , protocol
};
// createing data channel using RTC datachannel API name DC1
var dataChannel = PC.createDataChannel("DC1", dataChannelOptions);
dataChannel.onerror = function (error) {
console.log("DC Error:", error);
};
dataChannel.onmessage = function (event) {
console.log("DC Message:", event.data);
};
dataChannel.onopen = function () {
dataChannel.send(" Sending 123 "); // you can add file here in either strings/blob/array bufers almost anyways
};
dataChannel.onclose = function () {
console.log("DC is Closed");
};
`
PS : while sending files over datachannel API , it is advisable to break down the files into small chunks beforehand . I suggest chunk size of almost 10 - 15 KB .

Security with RijndaelManaged and ServicePointManager

I have a security question about RijndaelManaged and
ServicePointManager.
I have implemented a system where C# application is encrypting data, such as user credentials and some XML data. Then I use WebClient to send encrypted user credentials with some encrypted XML document containing instructions - to my Tomcat Java Web application. The job of the Java Application: is to decrypt user credentials and XML instructions – perform instructions and respond back to C# with an encrypted XML result.
All connections from my C# application to Tomcat server are with SSL enabled (Self signed certificate for now).
First Question: Given the fact that my C# application by default always connecting to my Server (only) with SSL enabled. Can I simply implement the call back function as:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
As I understand that the call back function is used to Identify and validate certificate used by the Server I’m connecting to. If I were to give that application to – say one of my clients to connect to my Server (with SSL enabled) – is the code above satisfactory? If client uses my application to connect to another server that is not known and I have no Idea about its SSL certificate status – the code above should be replaced with an actual certificate validation function. Does my question make sense?
Second Question: I have encryption/decryption implemented using RijndaelManaged in my C# application. But the key I’m using is part of the C# application – the application is obfuscated. As I understand this is not a secure way.
Is there a reliable way for the C# application to receive the encryption/decryption key from my Web application. Or is there a way for the key to be generated in C# application that can be used by Web application to decrypt the data – if so: how do I generate that key and most important how do I send it to the server in a reliable secure way. Since the connection is SSL – can the key simply be a part of the encrypted stream?
Here is code that I’m using for encryption in my C# app.
private const string KEY = "samplekey";
private const int KEY_SIZE = 128;
private const int KEY_BITS = 16;
private string Encrypt(string textToEncrypt)
{
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = KEY_SIZE;
rijndaelCipher.BlockSize = KEY_SIZE;
byte[] pwdBytes = Encoding.UTF8.GetBytes(KEY);
byte[] keyBytes = new byte[KEY_BITS];
int len = pwdBytes.Length;
if (len > keyBytes.Length)
{
len = keyBytes.Length;
}
Array.Copy(pwdBytes, 0, keyBytes, 0, len);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = keyBytes;
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
byte[] plainText = Encoding.UTF8.GetBytes(textToEncrypt);
return System.Convert.ToBase64String(transform.TransformFinalBlock(plainText, 0, plainText.Length));
}

WCF Named pipe message size problems

I am trying to get working a WCF named pipe communication between two processes on the same computer (on XP), but I am having trouble with "large" messages disappearing. The messages that disappear contain a largish byte array and I have narrowed the failure down to when the array is around 16k in size. Smaller than that and the message gets through. Larger than that and the sender says it went fine but it is never received. I have tried bumping up the buffer sizes on both sender and receiver as per this code for the server:
PipeServer pipeServer = new PipeServer();
ServiceHost serviceHost = new ServiceHost(pipeServer, new Uri[] { new Uri(baseName) });
NetNamedPipeBinding netNamedPipeBinding = new NetNamedPipeBinding();
netNamedPipeBinding.MaxBufferPoolSize = 5000000;
netNamedPipeBinding.MaxBufferSize = 500000;
netNamedPipeBinding.MaxReceivedMessageSize = 500000;
serviceHost.AddServiceEndpoint(typeof(ISSNPipeServer), netNamedPipeBinding, pipeName);
and this code for the client:
_callbacks = new PipeClientCallbacks();
NetNamedPipeBinding netNamedPipeBinding = new NetNamedPipeBinding();
netNamedPipeBinding.MaxBufferPoolSize = 5000000;
netNamedPipeBinding.MaxBufferSize = 500000;
netNamedPipeBinding.MaxReceivedMessageSize = 500000;
_pipeFactory = new DuplexChannelFactory<ISSNPipeServer>(_callbacks,
netNamedPipeBinding,
new EndpointAddress(_targetPipe));
_pipeProxy = _pipeFactory.CreateChannel();
I am eventually looking to transfer arrays in the 60KB size, but this is my first serious WCF experience and I have no idea even where to really start looking.
You can enable WCF tracing on the server to get more information as to what the failure is. Likely, you still need to increase the reader quotas associated with the binding (NetNamedPipeBinding.ReaderQuotas). Check the MaxArrayLength one in particular.