QDataStream not initialized while reading buffer from ipc fifo file descriptor - qt

I want to communicate between two application using fifo (ipc), I have created a fifo by "mkfifo MyPipe" command.
first App:
....
....
fd = open("MyPipe", O_NONBLOCK | O_WRONLY);
QByteArray buf;
QDataStream bdwr(&buf,QIODevice::WriteOnly);
bdwr.setVersion(kDSVersion);
myclassObjWr.lname = "AAAAA";
myclassObjWr.fname = "BBBBB";
bdwr << myclassObjWr.lname << myclassObjWr.fname ;
ssize_t written = write(fd,buf.data() , buf.length());
.....
.....
second App:
....
....
fd = open("MyPipe", O_NONBLOCK | O_RDONLY);
ssize_t nread;
QByteArray rxbuf;
static const QDataStream::Version kDSVersion = QDataStream::Qt_5_12;
QDataStream bdrd(&rxbuf, QIODevice::ReadWrite);
bdrd.setVersion(kDSVersion);
nread = read(fd, rxbuf.data(),200);
if ( nread > 0)
{
bdrd.writeRawData(rxbuf.data(),nread);
bdrd >> myclassObjrd.lname >> myclassObjrd.fname;
qDebug() << "lname: " << myclassObjrd.lname;
}
....
....
After reading the ipc fifo the "rxbuf" is initialized completely but "myclassObjrd.lname" and "myclassObjrd.fname" both are empty and do not initialize.

It was solved by using an intermediate unsigned char buffer to initialize QByteArray in the Second App as follows.
# ...
ssize_t nread;
QByteArray buf;
unsigned char* rxbuf;
static const QDataStream::Version kDSVersion = QDataStream::Qt_5_12;
QDataStream bdrd(&buf, QIODevice::ReadOnly);
bdrd.setVersion(kDSVersion);
rxbuf = (unsigned char*)malloc(200);
nread = read(fd, rxbuf,200);
if ( nread > 0)
{
for (int i = 0 ; i < nread; i++) {
buf[i] = rxbuf[i] ; //init QByteArray
}
bdrd >> myclassObjrd.lname >> myclassObjrd.fname;
qDebug() << "lname: " << myclassObjrd.lname;
}
# ...

Related

Openssl encrypt large file

I'm trying to encrypt a large file using OpenSSL AES_set_encrypt_key & AES_cbc_encrypt functions. I've written a C++ program to encrypt a file using AES_set_encrypt_key & AES_cbc_encrypt. The contents is got from a large file. I'm allocating memory in heap and calling AES_cbc_encrypt. But I observed only 8 bytes are getting encrypted. But when I allocate memory on stack, the function is working properly. Any help is highly appreciated.
unsigned char enc_out[encsize]; //working
unsigned char *enc_out = new unsigned char[encsize];//not working
`
QByteArray WebMessages::encryption(QString e_text) {
QByteArray ba = e_text.toLatin1();
char *encinput = strdup(ba.constData());
const int UserDataSize = strlen(encinput);
unsigned char *test2 = new unsigned char[UserDataSize];
for (int i = 0; i < UserDataSize; i++) {
test2[i] = encinput[i];
// qDebug() << test2[i];
}
int keylength = 128;
unsigned char aes_key[] = "";
unsigned char iv_enc[] = "";
unsigned char iv_dec[] = "";
const int encsize =
((UserDataSize + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
qDebug() << "$$$$$$$$$$$" << UserDataSize << AES_BLOCK_SIZE << encsize
<< sizeof(unsigned char *); //1481 16 1488 8
unsigned char enc_out[encsize];
// unsigned char *enc_out = new unsigned char[encsize];
AES_KEY enc_key;
AES_set_encrypt_key(aes_key, keylength, &enc_key);
AES_cbc_encrypt(test2, enc_out, UserDataSize, &enc_key, iv_enc,
AES_ENCRYPT);
qDebug() << "enc_out" << enc_out << sizeof(enc_out);
}
`

Sending Floats from server to client through socket (UDP)

So I am trying to send floats back and forth between clients and a server. I am able to send floats to the server and the server reads them perfectly. But unfortunately I can't seem to get the server sending the floats back to the other clients. Our current code that doesn't work looks like this.
Send function on server side
int Server::Send(float dt) {
{
char message[BUFLEN];
std::string msg = std::to_string(x2) + "#" + std::to_string(z2);
strcpy(message, (char*)msg.c_str());
if (sendto(server_socket, message, sizeof(message), 0, ptr->ai_addr, ptr->ai_addrlen) == SOCKET_ERROR)
{
std::cout << "Sendto() failed..." << std::endl;
}
else
{
std::cout << "Sent: " << message << "\n" << std::endl;
}
Receiving on Client side
int Client::Recieve(float dt) {
char buf[BUFLEN];
struct sockaddr_in fromAddr;
int fromlen;
fromlen = sizeof(fromAddr);
memset(buf, 0, BUFLEN);
int bytes_recieved = -1;
int sError = -1;
bytes_recieved = recvfrom(client_socket, buf, BUFLEN, 0, (struct sockaddr*) &fromAddr, &fromlen);
sError = WSAGetLastError();
if (sError != WSAEWOULDBLOCK && bytes_recieved > 0)
{
std::cout << "Recieved: " << buf << std::endl;
std::string tmp = buf;
std::size_t pos = tmp.find("#");
tmp = tmp.substr(0, pos - 1);
x2 = std::stof(tmp, NULL);
tmp = buf;
tmp = tmp.substr(pos + 1);
z2 = std::stof(tmp, NULL);
std::cout << "tx: " << x2 << " ty: " << z2 << std::endl;
}
else
std::cout << "Not Receiving" << std::endl;
Any help would be awesome!

Need help figuriing out correct syntax to update objects in global scope

I have this code:
int do_transact(ifstream & inFile, list<shared_ptr<Bike>> bikelist, status s)
{
int id, i = 0, size = bikelist.size();
float days;
string str, str2;
char name[50];
list<shared_ptr<Bike>>::iterator it = bikelist.begin();
if (s == NO_STATUS) //performs rental
{
inFile >> id;
inFile >> days;
inFile >> str;
inFile >> str2;
strcpy_s(name, str.c_str());
while (i < size)
{
if (id == (*it)->id_num) // rents bike
{
cout << "vvvvvv PERFORMING RENTAL vvvvvv" << endl << endl;
cout << "The price of this rental will be: $" << (days)*((*it)->cost_per_day) << endl;
strcpy_s((*it)->to_whom, name);
(*it)->rented_code = RENTED;
cout << "Thank you for your business!" << endl << endl;
return 0;
}
i++;
it++;
}
}
}
I am trying to change to_whom and rented_code in the original list, but it is not updating.
What is the syntax I need in order to change these values the way I need?

Qbytearray byte to int and storing it as string value

I want to convert byte data that stored in QBytearray into string value. that string value am using it for displaying in ui window..
QByteArray array;
array.append( 0x02 );
array.append( 0xC1);
qDebug()<<( uint )array[0]<<" "<<( uint )array[1];
uint i = 0x00000000;
i |= array[1];
qDebug()<<i;
uint j = 0x00000000 | ( array[0] << 8 );
qDebug()<<j;
i |= j;
bool b = false;
QString str = QString::number( i );
qDebug()<<str;
but the str prints "4294967233"...this code works for some of the bytes like 0x1, 0x45 and for some of other..but this code not working perfectly for all bytes of data into string..please help me with this and write code for this and post it here..thanks
All values equal or bigger than 0x80 interprets in your sample as negative values, so it need cast to unsigned type before bitwise operations.
QByteArray array;
array.append( 0x02 );
array.append( 0xC1);
unsigned int value = 0;
for (int i = 0; i < array.size(); i++)
value = (value << 8) | static_cast<unsigned char>(array[i]);
QString str = QString::number(value);
qDebug() << value << str;

Why does serial communication only work in one direction (chip->PC) with my code?

I am writing code for an Arduino Mega 2560 in C and I am trying to do bidirectional communication over the serial port. However, only sending data from the Arduino to the PC works - the other way doesn't. The RX LED on the arduino shortly lights up, but my code doesn't receive the data (the LED connected to "pin 13" doesn't light up). Does anyone know how to fix this?
Here's the code that's running on the arduino:
#define USART_BAUDRATE 500000
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
static void serial_init(void) {
// load upper 8 bits of the baud rate into the high byte of the UBRR register
UBRR0H = (BAUD_PRESCALE >> 8);
// load lower 8 bits of the baud rate into the low byte of the UBRR register
UBRR0L = BAUD_PRESCALE;
// 8data,1stopbit
UCSR0C = (0 << UMSEL00) | (1 << UCSZ00) | (1 << UCSZ01);
// turn on the transmission and reception circuitry
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (0 << UCSZ02);
}
static void sendbyte(uint8_t b) {
// do nothing until UDR is ready for more data to be written to it
while ((UCSR0A & (1 << UDRE0)) == 0) {};
// memory was cleared - write to it
UDR0 = b;
}
static void digi_init() {
// configure port B7 (arduino digital port 13) as output and set it low
PORTB = (0<<PB7);
DDRB = (1<<DDB7);
}
static void digi_set(int val) {
PORTB = (val<<PB7);
}
int main(void) {
serial_init();
digi_init();
while (1) {
if ((UCSR0A & (1 << RXC0)) == 1) {
// we got some data, light up the LED!
digi_set(1);
}
_delay_ms(50);
sendbyte('.');
}
}
And here's the code that's running on the PC:
int main(int argc, char *argv[]) {
char *serialdevicepath = "/dev/ttyACM0";
fprintf(stderr, "Connecting to serial device ...\n");
int serial_fd = open(serialdevicepath, O_RDWR | O_NOCTTY);
struct termios config;
if(tcgetattr(serial_fd, &config) < 0) exit(1);
config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON);
config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
config.c_cflag &= ~(CSIZE | PARENB);
config.c_cflag |= CS8;
config.c_cc[VMIN] = 1;
config.c_cc[VTIME] = 0;
if(cfsetispeed(&config, B500000) < 0 || cfsetospeed(&config, B500000) < 0) exit(1);
if(tcsetattr(serial_fd, TCSAFLUSH, &config) < 0) exit(1);
FILE *serial = fdopen(serial_fd, "r");
setbuf(stdin, NULL);
fcntl(0/*stdin*/, F_SETFL, O_NONBLOCK);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
setbuf(serial, NULL);
while (1) {
char c;
while (read(0, &c, 1) == 1) {
if (c != '+' && c != '-') continue;
uint8_t val = (c == '+') ? 42 : 41;
if (write(serial_fd, &val, 1) != 1) {
assert(0);
}
}
char b = fgetc(serial))&0xe0);
fprintf(stderr, "read 0x%x\n", b);
}
return 0;
}
(And yes, I am typing <+> on the PC so that it does send data. Also, I tried turning on the LED from the code directly and it worked.)
if ((UCSR0A & (1 << RXC0)) == 1)
That test is wrong, it will never be 1. The & operator here will produce either 0 or (1 << RXC0). Favor it this way instead:
if ((UCSR0A & (1 << RXC0)) != 0)
Or in C you'd typically write it this way since any non-zero value is logically true:
if (UCSR0A & (1 << RXC0))

Resources