Tor Socks4a Incomplete Response - c++

My application requires the use of Tor, over a socks4a proxy. Currently my response from tor is reported as successful but there is no reported Port or Ip, which is required for the 4a variant of socks, according to this wikipedia article SOCKS:
field 1: null byte
field 2: status, 1 byte:
0x5a = request granted
0x5b = request rejected or failed
0x5c = request failed
0x5d = request failed
field 3: network byte order port number, 2 bytes
field 4: network byte order IP address, 4 bytes
Tor is not filling fields 3 and 4, why is it doing this and how can i fix it?
Results of Socks Handshake:
Request: 0x04, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x77,
0x77, 0x77, 0x2E, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x00
Response from Tor: 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Source Code:
retval = connect(in_Socket, in_Socks, socksLen); //Connecting to Socks Server
if (retval != 0)
return retval; //Error if !=0
if (szUserId)
lPacketLen += strlen(szUserId); //If there is a userid, add its length to the packet length
lPacketLen += strlen(szHostName); //www.google.com
lPacketLen += 1;
char *packet = new char[lPacketLen];//Allocate a packet
memset(packet, 0x00, lPacketLen); //Init to zero
packet[0] = SOCKS_VER4; //Socks version: 0x4
packet[1] = 0x01; //Connect code
memcpy(packet + 2,(char *)&(((sockaddr_in *)in_szName)->sin_port),2); //Copy the port, 80 in this case
//Send a Malformed IP, as per Socks4a states
packet[4] = 0x00;
packet[5] = 0x00;
packet[6] = 0x00;
packet[7] = 0x8;
int IDLen = strlen(szUserId);
if (szUserId) //If there was a userid, copy it now
memcpy(packet + 8, szUserId, ++IDLen); //Account for null terminator /0
else
packet[8] = 0; //Send null ID if none provided
//Write the hostname we want Tor to resolve, i used www.google.com
memcpy(packet + 8 + IDLen, szHostName, strlen(szHostName) + 1);
if (m_Interval == 0)
Sleep(SOCKS_INTERVAL);
else
Sleep(m_Interval);
printf("\nRequest: ");
PrintArray(packet, lPacketLen);
send(in_Socket, packet, lPacketLen, 0); //Send the packet
delete[] packet; //Unallocate the packet
char reply[8]; //Allocate memory for the reply packet
memset(reply, 0, 8); //Init To 0
long bytesRecv = 0;
bytesRecv = recv(in_Socket, reply, 8, 0); //Get the reply packet
printf("\nResponse from Tor: ");
PrintArray(reply, 8);
//Check Reply Codes later

It appears that Tor treats this as an optional field, it seems to remember the connection address, resolve it, then forward any data after the handshake to the resolved domain.

Related

How to decrypt using openssl EVP?

I'm trying to decrypt a file using C (but I can change to C++), but I don't know how to use the EVP library correctly.
The console command that I want to replicate is:
openssl enc -rc2-ecb -d -in myfile.bin -iter 1 -md sha1 -pbkdf2 -pass pass:'Yumi'
My actual C code using EVP is:
unsigned char salt[8] = "Salted__";
ctx=EVP_CIPHER_CTX_new();
PKCS5_PBKDF2_HMAC_SHA1("Yumi", -1,
salt, 8, 1,
EVP_MAX_KEY_LENGTH, key);
EVP_DecryptInit(ctx, EVP_rc2_ecb(), key, iv);
pt = (unsigned char *)malloc(sz + EVP_CIPHER_CTX_block_size(ctx) + 1);
EVP_DecryptUpdate(ctx, pt, &ptlen, ciphertext, sz);
if (!EVP_DecryptFinal(ctx,&pt[ptlen],&tmplen)) {
printf("Error decrypting on padding \n");
} else {
printf("Succesful decryption\n");
}
I suppose that's not working because I have to declare something to use SHA1 instead of SHA256 (default on rc2-ecb), but I'm not seeing how to do it.
Any help will be appreciated
The following hex encoded ciphertext could be decrypted with the posted OpenSSL statement, if this data would be contained hex decoded in myfile.bin:
53616C7465645F5F2DC4C4867D3B9268C82E23A672D6698FB51D41EA8601367A9112623EC27CDEB18FD1444BDB8D8DE16F1A35706EC7FED266CB909D28BF6BEC
The decryption would result in:
The quick brown fox jumps over the lazy dog
For simplicity, the ciphertext is assigned directly and the loading of the ciphertext from a file is skipped:
unsigned char data[] = {
0x53, 0x61, 0x6C, 0x74, 0x65, 0x64, 0x5F, 0x5F, // Salted__
0x2D, 0xC4, 0xC4, 0x86, 0x7D, 0x3B, 0x92, 0x68, // Salt
0xC8, 0x2E, 0x23, 0xA6, 0x72, 0xD6, 0x69, 0x8F, 0xB5, 0x1D, 0x41, 0xEA, 0x86, 0x01, 0x36, 0x7A, // Ciphertext...
0x91, 0x12, 0x62, 0x3E, 0xC2, 0x7C, 0xDE, 0xB1, 0x8F, 0xD1, 0x44, 0x4B, 0xDB, 0x8D, 0x8D, 0xE1,
0x6F, 0x1A, 0x35, 0x70, 0x6E, 0xC7, 0xFE, 0xD2, 0x66, 0xCB, 0x90, 0x9D, 0x28, 0xBF, 0x6B, 0xEC };
int dataLength = sizeof(data) / sizeof(unsigned char);
For decryption, salt and ciphertext must first be separated, e.g.:
int ciphertextLength = dataLength - 16;
unsigned char* salt = (unsigned char*)malloc(sizeof(unsigned char) * 8);
unsigned char* ciphertext = (unsigned char*)malloc(sizeof(unsigned char) * ciphertextLength);
memcpy(salt, data + 8, 8); // Get 8 bytes salt (starts at index 8)
memcpy(ciphertext, data + 16, ciphertextLength); // Get ciphertext (starts at index 16)
The next step is to derive the key, see PKCS5_PBKDF2_HMAC, e.g.:
#define KEYSIZE 16
unsigned char key[KEYSIZE];
const char* password = "'Yumi'"; // The quotation marks (') in the openssl-statement are part of the password.
int passwordLen = strlen(password);
PKCS5_PBKDF2_HMAC(password, passwordLen, salt, 8, 1, EVP_sha1(), KEYSIZE, key);
Finally the decryption can be performed, see here and here, e.g.:
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_rc2_ecb(), NULL, NULL, NULL);
EVP_CIPHER_CTX_set_key_length(ctx, KEYSIZE); // RC2 is an algorithm with variable key size. Therefore the key size must generally be set.
EVP_DecryptInit_ex(ctx, NULL, NULL, key, NULL);
unsigned char* plaintext = (unsigned char*)malloc(sizeof(unsigned char) * ciphertextLength);
int length;
EVP_DecryptUpdate(ctx, plaintext, &length, ciphertext, ciphertextLength);
int plaintextLength = length;
EVP_DecryptFinal_ex(ctx, plaintext + plaintextLength, &length);
plaintextLength += length;
printf("Plaintext: "); for (int i = 0; i < plaintextLength; i++) { printf("%c", plaintext[i]); } printf("\n");
For simplicity, the code doesn't include exception handling and memory release.
Note the following:
Some of the parameters used in the posted OpenSSL statement are insecure, e.g. the ECB mode and an iteration count of 1. Instead, a mode with an IV should be used and an iteration count of 10,000 or larger if performance allows.
OpenSSL generates a random 8 bytes salt during encryption, which is used to derive the key. The ciphertext consists of the ASCII encoding of Salted__, followed by the 8 bytes salt, followed by the actual ciphertext, here. Just this format is expected by the posted OpenSSL statement for decryption.
RC2 defines a variable key size. The posted OpenSSL statement uses a size of 16 bytes.
The -pass pass: option specifies the password without quotation marks, i.e. in the posted OpenSSL statement the quotation marks are part of the password.

Openssl C++ AES decryption adding unexpected symbols

I'm trying to decrypt in C++ a file that have been encrypted with the Linux command : openssl enc -aes-256-cbc -nosalt -K "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" -iv "5DF6E0E2761359D30A8275058E299FCC" -p -in file.json -out file.enc
The decryption works well, but unexpected symbols appear at the end of the file when I print it in the terminal, as in the following image Image
Here is my C++ code, can someone help me ?
int main(int argc, char **argv)
{
EVP_CIPHER_CTX *en, *de;
en = EVP_CIPHER_CTX_new();
de = EVP_CIPHER_CTX_new();
unsigned char key_data[] = {0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B,0x78, 0x52, 0xB8, 0x55};
int key_data_len = 32;
std::ifstream in("file.enc");
std::string contents((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
unsigned char iv[] = {0x5D, 0xF6, 0xE0, 0xE2, 0x76, 0x13, 0x59, 0xD3, 0x0A, 0x82, 0x75, 0x05, 0x8E, 0x29, 0x9F, 0xCC};
EVP_CIPHER_CTX_init(en);
EVP_EncryptInit_ex(en, EVP_aes_256_cbc(), NULL, key_data, iv);
EVP_CIPHER_CTX_init(de);
EVP_DecryptInit_ex(de, EVP_aes_256_cbc(), NULL, key_data, iv);
char *plaintext;
int len = strlen(contents.c_str())+1;
plaintext = (char *)aes_decrypt(de, (unsigned char *)contents.c_str(), &len);
printf("%s", plaintext);
free(plaintext);
EVP_CIPHER_CTX_cleanup(en);
EVP_CIPHER_CTX_cleanup(de);
}
And the function to decrypt :
unsigned char *aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len)
{
int p_len = *len, f_len = 0;
unsigned char *plaintext = (unsigned char *)calloc(sizeof(char*), p_len);
EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL);
EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len);
EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len);
*len = p_len + f_len;
return plaintext;
}
SOLVED : I had to remove the PKCS#7 padding added by the encoder PKCS#7 Padding
The input length is incorrect - strlen(contents.c_str()) + 1 will either return length including additional null byte which should not be included as it is not part of encrypted data, or length of data to the first null byte in encrypted data if there is one. You should use contents.size() instead.
This causes EVP_DecryptUpdate to decrypt all data including last block with padding and expect more data and EVP_DecryptFinal_ex to fail after that. With correct length the padding from last block will be stripped as expected.
There's also issue with output buffer length - it's sizeof(char*) * p_len instead of sizeof(char) * (p_len + EVP_CIPHER_block_size(EVP_aes_256_cbc())). EVP_DecryptUpdate requires output buffer to be large enough to hold input length + cipher block size.
You should also make sure to use only len data in plaintext buffer - printf will output data until null byte, which might not be included in decrypted data.

C++ AES Decrypt and Nodejs AES Decrypt producing different outputs

I've reimplemented this AES c++ decryption in nodejs.
The "buffer" contains the encrypted content.
The "decryptKey" contains the key to decrypt the "buffer".
The "expectedOutput" contains the expected output.
In order to bypass the bad decrypt exception thrown by node I had to disable the autoPadding in my crypt object.
To simplify I added the c++ code and I added tests to three different algorithms (AES-128-ECB, AES-192-ECB, AES-256-ECB). None of the decrypt results match the C++ output.
What am I missing?
var crypto = require('crypto');
var buffer = new Buffer([
0x5e,0x51,0xa3,0x53,0x9d,0xe7,0xe5,0xd3,
0xee,0x30,0xbb,0xf8,0x0c,0x72,0x9f,0x80
]);
var decryptKey = new Buffer([
0x36, 0x46, 0xb4, 0xf6,
0x8e, 0x6d, 0xdc, 0xf4,
0xb0, 0x31, 0x7e, 0x81,
0x6b, 0x5d, 0x96, 0x55
])
/*
After looking to my C++ code I noticed that despite of providing a 32 length key the 128 argument ensures that only the first 16 bytes are used
var decryptKey = new Buffer([
0x36, 0x46, 0xb4, 0xf6,
0x8e, 0x6d, 0xdc, 0xf4,
0xb0, 0x31, 0x7e, 0x81,
0x6b, 0x5d, 0x96, 0x55, // 16
0x15, 0x9c, 0x78, 0x54,
0x8c, 0xca, 0x3e, 0x39,
0x2d, 0x49, 0x75, 0x5d,
0xa1, 0x1a, 0xc3, 0xe3 // 32
])*/
var expectedOutput = new Buffer([
0xc8,0x6c,0x8f,0x2b,0xe8,0x21,0xc4,0x2e,
0xfb,0x4a,0x8e,0x8b,0xc3,0x94,0x19,0xc2
]);
// aes_context aes_ctx;
function decrypt(data, password, algorithm, padding){
if (padding === void 0) padding = true;
algorithm = algorithm || 'aes-128-ecb';
//aes_setkey_dec( &aes_ctx, digest, 128 );
var crypt = crypto.createDecipher(algorithm,password);
crypt.setAutoPadding(padding);
// aes_crypt_ecb( &aes_ctx, AES_DECRYPT, buffer, buffer );
var res = crypt.update(data, null, 'hex')
res += crypt.final('hex');
return new Buffer(res,'hex');
}
// aes_setkey_dec( &aes_ctx, digest, 128 );
var algoList = [
'aes-128-ecb',
'aes-192-ecb',
'aes-256-ecb'
];
for (var i = 0; i<= 1; i++){
console.log('\n ******* AUTO PADDING: ' + (padding ? 'ON': 'OFF') + ' ********* ');
var padding = i === 0;
for (let algo of algoList){
try {
var output = decrypt(buffer, decryptKey, algo, padding);
console.log(algo + ' => ' + output.toString('hex') + ' < ' + (Buffer.compare(expectedOutput, output) === 0 ? 'ok' : 'ko'))
} catch (err){
console.log('Failed to perform ' + algo + ' with autopadding ' + (padding ? ' on ': ' off ') + ' due to ' + err.message);
}
}
}
/*
******* AUTO PADDING: OFF *********
Failed to perform aes-128-ecb with autopadding on due to error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
Failed to perform aes-192-ecb with autopadding on due to error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
Failed to perform aes-256-ecb with autopadding on due to error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
******* AUTO PADDING: ON *********
aes-128-ecb => d9817f142f9bca262b67f6a6be570345 < ko
aes-192-ecb => 9181784373bb6060c04c9ba75de26322 < ko
aes-256-ecb => c5945203368de477e5f0dbeedeb2189f < ko
*/
Heres the c++ code
#include "aes.h"
#include "sha2.h"
int main(int argc, char *argv[]) {
unsigned char data[16] = {
0x5e,0x51,0xa3,0x53,0x9d,0xe7,0xe5,0xd3,0xee,0x30,0xbb,0xf8,0x0c,0x72,0x9f,0x80
};
unsigned char key[32] = {
0x36, 0x46, 0xb4, 0xf6,
0x8e, 0x6d, 0xdc, 0xf4,
0xb0, 0x31, 0x7e, 0x81,
0x6b, 0x5d, 0x96, 0x55, // 16
0x15, 0x9c, 0x78, 0x54,
0x8c, 0xca, 0x3e, 0x39,
0x2d, 0x49, 0x75, 0x5d,
0xa1, 0x1a, 0xc3, 0xe3 // 32
};
aes_context aes_ctx;
aes_setkey_dec(&aes_ctx, key, 128);
aes_crypt_ecb(&aes_ctx, AES_DECRYPT, data, data);
for (int i = 0; i< sizeof(data); ++i)
std::cout << std::hex << (int)data[i];
/* Output => c86c8f2be821c42efb4a8e8bc39419c2*/
}
references:
https://tls.mbed.org/discussions/generic/question-about-using-aes
http://aes.online-domain-tools.com/link/133660agcLyPgFri4s/ - Example of decryption online
The solution based in answer below
var crypto = require('crypto')
var buffer = new Buffer([
0x5e,0x51,0xa3,0x53,0x9d,0xe7,0xe5,0xd3,
0xee,0x30,0xbb,0xf8,0x0c,0x72,0x9f,0x80
]);
var decryptKey = new Buffer([
0x36, 0x46, 0xb4, 0xf6,
0x8e, 0x6d, 0xdc, 0xf4,
0xb0, 0x31, 0x7e, 0x81,
0x6b, 0x5d, 0x96, 0x55
])
var expectedOutput = new Buffer([
0xc8,0x6c,0x8f,0x2b,0xe8,0x21,0xc4,0x2e,
0xfb,0x4a,0x8e,0x8b,0xc3,0x94,0x19,0xc2
]);
// aes_context aes_ctx;
function decrypt(data, password, algorithm, padding){
if (padding === void 0) padding = true;
algorithm = algorithm || 'aes-128-ecb';
//aes_setkey_dec( &aes_ctx, digest, 128 );
var crypt = crypto.createDecipheriv(algorithm,password, new Buffer([]));//new Buffer(32).fill(0).byteLength
crypt.setAutoPadding(padding);
// aes_crypt_ecb( &aes_ctx, AES_DECRYPT, buffer, buffer );
var res = crypt.update(data, null,'hex')
+ crypt.final('hex');
return new Buffer(res,'hex');
}
// aes_setkey_dec( &aes_ctx, digest, 128 );
var output = decrypt(buffer, decryptKey, 'aes-128-ecb', false);
console.log(Buffer.compare(expectedOutput, output) === 0 ? 'ok' : 'ko');
The deprecated crypto.createDecypher() derives the key from the password argument:
The implementation of crypto.createDecipher() derives keys using the OpenSSL function EVP_BytesToKey with the digest algorithm set to MD5, one iteration, and no salt.
What you want instead is to use a raw key. For that you should use crypto.createDecipheriv() instead:
var crypt = crypto.createDecipheriv(algorithm,password,new Buffer([]));
(In ECB mode the IV can be empty)
Of course, the key length must then match the requested algorithm (128, 192 or 256 bits). You key is 128 bits, so only aes-128-ecb will work.
The reason you need to pass false to setAutoPadding is that your ciphertext is not padded. You haven't included your encryption code that generates the ciphertext, but I can tell from the length of it that it is not padded, because a plaintext of one block size in length, when encrypted using PKCS#7 padding, will produce a ciphertext that is two block sizes in length, rather than the single block that you have.
The reason this decrypts with aes_crypt_ecb is that it looks like aes_crypt_ecb simply performs individual block encryption/decryption, so does not do any padding or unpadding. The Javscript code though, if passed true to the setAutoPadding function, will be expecting padding (probably PKCS#7). Which will of course fail because your encryption has not used padding.
Ideally you should modify your encryption code so that it uses proper padding when doing the encryption, as this is much more secure than not using padding. Otherwise you will need to make sure that your call to setAutoPadding is passing false when doing the decryption, so the Javascript knows there is no padding.

Missing something when decompressing HTTP gzipped response

I have recently been setting up various testing environments and in this cas I nneed to read and decode a gzip response from a HTTP server. I know what I have so far works as I have tested it with wireshark and hardcoded data as outlined below, my question is what is wrong with how I am handling the gizzped data from a HTTP server?
Here is what Im using:
From this thread http://www.qtcentre.org/threads/30031-qUncompress-data-from-gzip I am using the gzipDecopress function with the data provided and seeing that it works.
QByteArray gzipDecompress( QByteArray compressData )
{
//Hardcode sample data
const char dat[40] = {
0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA, 0x2E, 0x2E, 0x49, 0x2C, 0x29,
0x2D, 0xB6, 0x4A, 0x4B, 0xCC, 0x29, 0x4E, 0xAD, 0x05, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00,
0x2A, 0x63, 0x18, 0xC5, 0x0E, 0x00, 0x00, 0x00};
compressData = QByteArray::fromRawData( dat, 40);
//decompress GZIP data
//strip header and trailer
compressData.remove(0, 10);
compressData.chop(12);
const int buffersize = 16384;
quint8 buffer[buffersize];
z_stream cmpr_stream;
cmpr_stream.next_in = (unsigned char *)compressData.data();
cmpr_stream.avail_in = compressData.size();
cmpr_stream.total_in = 0;
cmpr_stream.next_out = buffer;
cmpr_stream.avail_out = buffersize;
cmpr_stream.total_out = 0;
cmpr_stream.zalloc = Z_NULL;
cmpr_stream.zalloc = Z_NULL;
if( inflateInit2(&cmpr_stream, -8 ) != Z_OK) {
qDebug() << "cmpr_stream error!";
}
QByteArray uncompressed;
do {
int status = inflate( &cmpr_stream, Z_SYNC_FLUSH );
if(status == Z_OK || status == Z_STREAM_END) {
uncompressed.append(QByteArray::fromRawData((char *)buffer, buffersize - cmpr_stream.avail_out));
cmpr_stream.next_out = buffer;
cmpr_stream.avail_out = buffersize;
} else {
inflateEnd(&cmpr_stream);
}
if(status == Z_STREAM_END) {
inflateEnd(&cmpr_stream);
break;
}
}while(cmpr_stream.avail_out == 0);
return uncompressed;
}
When the data is hardcoded as in that example, the string is decompressed. However, when I read the response from a HTTP server and store it in a QByteArray, it cannot be uncompressed. I am reading the response as follows and I can see it works when comparing the results on wireshark
//Read that length of encoded data
char EncodedData[ LengthToRead ];
memset( EncodedData, 0, LengthToRead );
recv( socketDesc, EncodedData, LengthToRead, 0 );
EndOfData = true;
//EncodedDataBytes = QByteArray((char*)EncodedData);
EncodedDataBytes = QByteArray::fromRawData(EncodedData, LengthToRead );
I assume i am missing some header or byte order when reading the response, but at the moment have no idea what. Any help very welcome!!
EDIT: So I have been looking at this a little more over the weekend and at the moment im trying to test the encode and decode of the given hex string, which is "{status:false}" in plain text. I have tried to use online gzip encoders such as http://www.txtwizard.net/compression but it returns some ascii text that does not match the hex string in the above code. When I use PHPs gzcompress( "{status:false}", 1) function it gives me non-ascii values, that I cannot copy/paste to test since they are ascii. So I am wondering if there is any standard reference for gzip encode/decode? It is definitely not in some special encoding since both firefox and wireshark can decode the packets, but my software cannot.
So the issue was with my gzip function, the correct function I found on this link: uncompress error when using zlib
As mentioned above by Cornstalks the infalteInit2 function needs to take MAX_WBITS+16 as its max bit size, I think that was the issue. If anybody knows any libraries or plugins to handle this please post them here! I am surprised that this had to be coded manually when it is so commonly used by HTTP clients/servers.

Send Hex Bytes To A Serial Port

I am attempting to send hexadecimal bytes to a serial com port. The issue is that the segment that sends the command apparently wants a system string instead of an integer (error C2664 "cannot convert parameter 1 from 'int' to 'System::String ^'). I have looked for a way to send an integer instead but have had no luck. (I have tried sending string representations of the hexadecimal values, but the device did not recognize the commands)
Main part of Code
private: System::Void poll_Click(System::Object^ sender, System::EventArgs^ e)
{
int i, end;
double a = 1.58730159;
String^ portscan = "port";
String^ translate;
std::string portresponse [65];
std::fill_n(portresponse, 65, "Z");
for (i=1;i<64;i++)
{
if(this->_serialPort->IsOpen)
{
// Command 0 generator
int y = 2;
y += i;
int command0[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, dectohex(i), 0x00, 0x00, dectohex(y)};
for (end=0;end<10;end++)
{
this->_serialPort->WriteLine(command0[end]);
}
translate = (this->_serialPort->ReadLine());
MarshalString(translate, portresponse [i]);
if(portresponse [i] != "Z")
{
comboBox7->Items->Add(i);
}
this->progressBar1->Value=a;
a += 1.58730159;
}
}
}
Here is the function dectohex:
int dectohex(int i)
{
int x = 0;
char hex_array[10];
sprintf (hex_array, "0x%02X", i);
string hex_string(hex_array);
x = atoi(hex_string.c_str());
return x;
}
This is what solved my problem, courtesy of Jochen Kalmbach
auto data = gcnew array<System::Byte> { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x00, 0xBD };
_serialPort->Write(data, 0, data->Length);
Replaced this
this->_serialPort->WriteLine(command0[end]);
You cannot sent an integer over a serial line.... you can only sent BYTES (7-8 bit)!
You need to choose what you want to do:
Sent characters: So the "number" 12 will be converted into the bytes
_serialPort->Write(12.ToString());
// => 0x49, 0x50
Sent the integer (4 bytes) as little endian
auto data = System::BitConverter::GetBytes(12);
_serialPort->Write(data, 0, data->Length);
// => 0x0c, 0x00, 0x00, 0x00
Or you write just a single byte:
auto data = gcnew array<System::Byte> { 12 };
_serialPort->Write(data, 0, data->Length);
// => 0x0c
Or write an byte array:
auto data = gcnew array<System::Byte> { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x00, 0xBD };
_serialPort->Write(data, 0, data->Length);
// => 0xFF 0xFF 0xFF 0xFF 0xFF 0x02 0xBF 0x00 0x00 0xBD