Weird results from multiplying uint16_t variable with a number - c

I have a very simple piece of C code that gives me weird result. I'm developing a simple wireless sensor network application for Micaz motes. It seems to have ATmega128L 8 bit AVR microprocessors. I'm using AVR studio to write and compile the code.
uint16_t myvariable;
uint16_t myresult;
myresult = myvariable*256;
When myvariable is 3, I found myresult was always reset to 512. Just wondering why it works like this. My guess is, the mixture of such a literal number 256 and uint16_t magically causes the problem. But I don't know why. Could anybody give a detailed explanation on this? Appreciate for any help!
More detailed source code is as follows.
static uint16_t myvariable[2];
static uint8_t AckMsg[32];
uint16_t myresult[MAX_SENDERS];
void protocol()
{
if(thisnodeid != 5){ // sender nodes
while (1)
{
if(AckReceived && !MsgSent) {
// If ACK received and a new message not sent yet,
// send a new message on sending node.
}
else if(!AckReceived && MsgSent)
{
lib_radio_receive_timed(16, 32, AckMsg, 120);
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
// Bug!!!, variable overflowed.
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
}
}
}
}
What I really want to figure out is, how the compiler compiles following line of code, because I know it's this line of code causes the bug. Thanks in advance for any information!
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
When myvariable[1]=3, myvariable[0]=0, I always get myresult[] = 512. Looks 768 is always reset to 512. Just don't know why.

I tried this code without any problem on a standard system:
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define MAX_SENDERS 10
static uint16_t myvariable[2];
static uint8_t AckMsg[32];
uint16_t myresult[MAX_SENDERS];
main()
{
AckMsg[0] = 0;
AckMsg[1] = 3;
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
myresult[0] = 256*myvariable[1] + myvariable[0];
printf("%d", (int)myresult[0]);
}
So to debug you code, you should try to replace the lines :
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
// Bug!!!, variable overflowed.
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
by :
uint16_t tmp;
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
tmp = 256*myvariable[1] + myvariable[0];
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
printf("%d %d\n", (int)(AckMsg[0]), (int)(AckMsg[1]));
printf("%d %d\n", (int)(thisnodeid), (int)(MAX_SENDERS));
printf("%d %d\n", (int)(myvariable[0]), (int)(myvariable[1]));
printf("%d %d\n", (int)(tmp), (int)(myresult[thisnodeid]));
This may bring useful information on the origin of the problem.
If you cannot print something in you debugger, you can try the following thing:
uint16_t i = 0;
uint16_t n = 255;
myresult[thisnodeid] += myvariable[1];
while (i != n) {
myresult[thisnodeid] += myvariable[1];
i += 1;
}
myresult[thisnodeid] += myvariable[0];
It will be slow but it may allow you to detect where the overlow is actually happening, because the only variable that will be greater than 255 is myresult.

Related

This program is use to read the acceleration. Can anyone explain what does "int16_t pDataXYZ[3] = {0};" mean? BOLDED below

#include "main.h"
#include "app_x-cube-ai.h"
#include "ai_platform.h"
#include "network.h"
#include "network_data.h"
#include "stm32l475e_iot01.h"
#include "stm32l475e_iot01_accelero.h"
#include <math.h>
#include <stdio.h>
This is the include file.
ai_handle network;
float aiInData[AI_NETWORK_IN_1_SIZE];
float aiOutData[AI_NETWORK_OUT_1_SIZE];
uint8_t activations[AI_NETWORK_DATA_ACTIVATIONS_SIZE];
const char* activities[AI_NETWORK_OUT_1_SIZE] = {
"stationary", "walking", "running"
};
The main code reads here for displaying the XYZ axis
int main(void)
{
BSP_ACCELERO_Init();
int16_t pDataXYZ[3] = {0}; // ?????
while (1)
{
BSP_ACCELERO_AccGetXYZ(pDataXYZ);
snprintf(str_acc,100," X-axis = %d \n\r", pDataXYZ[0]);
snprintf(str_acc,100," Y-axis = %d \n\r", pDataXYZ[1]);
snprintf(str_acc,100," Z-axis = %d \n\r", pDataXYZ[2]);
aiInData[write_index + 0] = (float) pDataXYZ[0] / 4000.0f;
aiInData[write_index + 1] = (float) pDataXYZ[1] / 4000.0f;
aiInData[write_index + 2] = (float) pDataXYZ[2] / 4000.0f;
write_index += 3;
if (write_index == AI_NETWORK_IN_1_SIZE) {
write_index = 0;
printf("Running inference\r\n");
AI_Run(aiInData, aiOutData);
/* Output results */
for (uint32_t i = 0; i < AI_NETWORK_OUT_1_SIZE; i++) {
printf("%8.6f ", aiOutData[i]);
}
uint32_t class = argmax(aiOutData, AI_NETWORK_OUT_1_SIZE);
printf(": %d - %s\r\n", (int) class, activities[class]);
}
}
}
What does write_index and pDataXYZ mean? Also how do you convert the XYZ axis into acceleration?
I cannot display the last line saying printf(": %d - %s\r\n", (int) class, activities[class]);
First I do not have enough reputation for comment so this is not a full answer. As Ian Abbott mentioned in the comments section the pDataXYZ it is just a 16 bit element size array initialized to 0, it seems that the function BSP_ACCELERO_AccGetXYZ is getting the acceleration in a specific format that is not described in your code, also the str_acc buffer is been loaded with the information of the pDataXYZ array but we can not know where it is been used only by taking a look to the code you share. write_index seems to be a base index where the information in the aiInData array should be but we can not be sure of it until you post all the code. Regarding the conversion you will need to give more information and investigate in the device data sheet the format of the data. this information could be in the division by 4000.0 or the AI_Run function.

figure out why my RC4 Implementation doesent produce the correct result

Ok I am new to C, I have programmed in C# for around 10 years now so still getting used to the whole language, Ive been doing great in learning but im still having a few hickups, currently im trying to write a implementation of RC4 used on the Xbox 360 to encrypt KeyVault/Account data.
However Ive run into a snag, the code works but it is outputting the incorrect data, I have provided the original c# code I am working with that I know works and I have provided the snippet of code from my C project, any help / pointers will be much appreciated :)
Original C# Code :
public struct RC4Session
{
public byte[] Key;
public int SBoxLen;
public byte[] SBox;
public int I;
public int J;
}
public static RC4Session RC4CreateSession(byte[] key)
{
RC4Session session = new RC4Session
{
Key = key,
I = 0,
J = 0,
SBoxLen = 0x100,
SBox = new byte[0x100]
};
for (int i = 0; i < session.SBoxLen; i++)
{
session.SBox[i] = (byte)i;
}
int index = 0;
for (int j = 0; j < session.SBoxLen; j++)
{
index = ((index + session.SBox[j]) + key[j % key.Length]) % session.SBoxLen;
byte num4 = session.SBox[index];
session.SBox[index] = session.SBox[j];
session.SBox[j] = num4;
}
return session;
}
public static void RC4Encrypt(ref RC4Session session, byte[] data, int index, int count)
{
int num = index;
do
{
session.I = (session.I + 1) % 0x100;
session.J = (session.J + session.SBox[session.I]) % 0x100;
byte num2 = session.SBox[session.I];
session.SBox[session.I] = session.SBox[session.J];
session.SBox[session.J] = num2;
byte num3 = data[num];
byte num4 = session.SBox[(session.SBox[session.I] + session.SBox[session.J]) % 0x100];
data[num] = (byte)(num3 ^ num4);
num++;
}
while (num != (index + count));
}
Now Here is my own c version :
typedef struct rc4_state {
int s_box_len;
uint8_t* sbox;
int i;
int j;
} rc4_state_t;
unsigned char* HMAC_SHA1(const char* cpukey, const unsigned char* hmac_key) {
unsigned char* digest = malloc(20);
digest = HMAC(EVP_sha1(), cpukey, 16, hmac_key, 16, NULL, NULL);
return digest;
}
void rc4_init(rc4_state_t* state, const uint8_t *key, int keylen)
{
state->i = 0;
state->j = 0;
state->s_box_len = 0x100;
state->sbox = malloc(0x100);
// Init sbox.
int i = 0, index = 0, j = 0;
uint8_t buf;
while(i < state->s_box_len) {
state->sbox[i] = (uint8_t)i;
i++;
}
while(j < state->s_box_len) {
index = ((index + state->sbox[j]) + key[j % keylen]) % state->s_box_len;
buf = state->sbox[index];
state->sbox[index] = (uint8_t)state->sbox[j];
state->sbox[j] = (uint8_t)buf;
j++;
}
}
void rc4_crypt(rc4_state_t* state, const uint8_t *inbuf, uint8_t **outbuf, int buflen)
{
int idx = 0;
uint8_t num, num2, num3;
*outbuf = malloc(buflen);
if (*outbuf) { // do not forget to test for failed allocation
while(idx != buflen) {
state->i = (int)(state->i + 1) % 0x100;
state->j = (int)(state->j + state->sbox[state->i]) % 0x100;
num = (uint8_t)state->sbox[state->i];
state->sbox[state->i] = (uint8_t)state->sbox[state->j];
state->sbox[state->j] = (uint8_t)num;
num2 = (uint8_t)inbuf[idx];
num3 = (uint8_t)state->sbox[(state->sbox[state->i] + (uint8_t)state->sbox[state->j]) % 0x100];
(*outbuf)[idx] = (uint8_t)(num2 ^ num3);
printf("%02X", (*outbuf)[idx]);
idx++;
}
}
printf("\n");
}
Usage (c#) :
byte[] cpukey = new byte[16]
{
...
};
byte[] hmac_key = new byte[16]
{
...
};
byte[] buf = new System.Security.Cryptography.HMACSHA1(cpukey).ComputeHash(hmac_key);
MessageBox.Show(BitConverter.ToString(buf).Replace("-", ""), "");
Usage(c):
const char cpu_key[16] = { 0xXX, 0xXX, 0xXX };
const unsigned char hmac_key[16] = { ... };
unsigned char* buf = HMAC_SHA1(cpu_key, hmac_key);
uint8_t buf2[20];
uint8_t buf3[8] = { 0x1E, 0xF7, 0x94, 0x48, 0x22, 0x26, 0x89, 0x8E }; // Encrypted Xbox 360 data
uint8_t* buf4;
// Allocated 8 bytes out.
buf4 = malloc(8);
int num = 0;
while(num < 20) {
buf2[num] = (uint8_t)buf[num]; // convert const char
num++;
}
rc4_state_t* rc4 = malloc(sizeof(rc4_state_t));
rc4_init(rc4, buf2, 20);
rc4_crypt(rc4, buf3, &buf4, 8);
Now I have the HMACsha1 figured out, im using openssl for that and I confirm I am getting the correct hmac/decryption key its just the rc4 isnt working, Im trying to decrypt part of the Kyevault that should == "Xbox 360"||"58626F7820333630"
The output is currently : "0000008108020000" I do not get any errors in the compilation, again any help would be great ^.^
Thanks to John's help I was able to fix it, it was a error in the c# version, thanks John !
As I remarked in comments, your main problem appeared to involve how the output buffer is managed. You have since revised the question to fix that, but I describe it anyway here, along with some other alternatives for fixing it. The remaining problem is discussed at the end.
Function rc4_crypt() allocates an output buffer for itself, but it has no mechanism to communicate a pointer to the allocated space back to its caller. Your revised usage furthermore exhibits some inconsistency with rc4_crypt() with respect to how the output buffer is expected to be managed.
There are three main ways to approach the problem.
Function rc4_crypt() presently returns nothing, so you could let it continue to allocate the buffer itself, and modify it to return a pointer to the allocated output buffer.
You could modify the type of the outbuf parameter to uint8_t ** to enable rc4_crypt() to set the caller's pointer value indirectly.
You could rely on the caller to manage the output buffer, and make rc4_crypt() just write the output via the pointer passed to it.
The only one of those that might be tricky for you is #2; it would look something like this:
void rc4_crypt(rc4_state_t* state, const uint8_t *inbuf, uint8_t **outbuf, int buflen) {
*outbuf = malloc(buflen);
if (*outbuf) { // do not forget to test for failed allocation
// ...
(*outbuf)[idx] = (uint8_t)(num2 ^ num3);
// ...
}
}
And you would use it like this:
rc4_crypt(rc4, buf3, &buf4, 8);
... without otherwise allocating any memory for buf4.
The caller in any case has the responsibility for freeing the output buffer when it is no longer needed. This is clearer when it performs the allocation itself; you should document that requirement if rc4_crypt() is going to be responsible for the allocation.
The remaining problem appears to be strictly an output problem. You are apparently relying on print statements in rc4_crypt() to report on the encrypted data. I have no problem whatever with debugging via print statements, but you do need to be careful to print the data you actually want to examine. In this case you do not. You update the joint buffer index idx at the end of the encryption loop before printing a byte from the output buffer. As a result, at each iteration you print not the encrypted byte value you've just computed, but rather an indeterminate value that happens to be in the next position of the output buffer.
Move the idx++ to the very end of the loop to fix this problem, or change it from a while loop to a for loop and increment idx in the third term of the loop control statement. In fact, I strongly recommend for loops over while loops where the former are a good fit to the structure of the code (as here); I daresay you would not have made this mistake if your loop had been structured that way.

Simple calloc and FILE code randomly crashes on windows

I have a code that is supposed to generate a curve for regulation purposes which works fine.
Coming from a Linux environment, I did not really know how to code on Windows (which I have to use at work) so I just went on and downloaded Code::Blocks with MinGW.
Now the problem is the following : My code works, but sometimes it crashes. I tried it on Linux and I don't have any problem running it, on Windows however, sometimes it will work, sometimes it won't and tell me this.
Problem signature:
Problem Event Name: APPCRASH
Application Name: TabGen.exe
Application Version: 0.0.0.0
Application Timestamp: 02881c68
Fault Module Name: ntdll.dll
Fault Module Version: 6.1.7601.23418
Fault Module Timestamp: 5708a73e
Exception Code: c0000005
Exception Offset: 00032a62
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 2055
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
To be fairly honest, I don't really understand. I tried looking up "Exception code c0000005 windows" which apparently means "access violation", but I do not understand where it comes from because as stated it sometimes works sometimes it doesn't.
Is it MinGW related ? Have I done something wrong in my code ? I have a function mk_cp_table (which always uses 4096 values, that's why it is not a function parameter) but I'm pretty positive it is alright.
Also if you are wondering why I'm using calloc instead of an array, it's again because of an error I don't understand. The fprintf at the end in the last function did not work if I had my values in an array (however displaying them with printf alone worked perfectly, but fprintf only left blank files whenever I would run it).
Any ideas ?
My code :
#include <stdio.h>
#include <stdlib.h>
void tab2file(FILE*, int, int*);
void mk_cp_table (int*, float, float, float, int, float, float, int);
int main (void)
{
FILE* cp_file = fopen("cp_table.txt", "w");
if (cp_file == NULL)
{
perror("failed fopen for cp_file\n");
exit(EXIT_FAILURE);
}
int* cp_table = calloc((size_t) 4096, sizeof (int));
if (cp_table == NULL)
{
fclose(cp_file);
perror("failed calloc for cp_table\n");
exit(EXIT_FAILURE);
}
/* Generate curves */
mk_cp_table(
cp_table,
0.142, /* scale */
20, /* zeroed distance 0 (negative part) */
0.04, /* slope 0 */
120, /* range 0 */
20, /* zeroed distance 1 (positive part) */
0.04, /* slope 1 */
120 /* range 1 */
);
printf("\ntable generated\n");
tab2file(cp_file, 4096, cp_table);
printf("\ntables written to files\n");
fclose(cp_file);
free(cp_table);
return EXIT_SUCCESS;
}
void tab2file(FILE* file, int size, int* table)
{
int i;
for (i = 0; i < size; i++)
fprintf(file, "%d\n", table[i]);
}
void mk_cp_table(int* table, float scale, float zeroes_0, float slope_0, int range_0, float zeroes_1, float slope_1, int range_1)
{
int i;
int value;
zeroes_0 = zeroes_0 / scale;
zeroes_1 = zeroes_1 / scale;
for (i = 0; i < 2048; i++)
{
if (i < zeroes_1)
value = 0;
else
value = (i - zeroes_1) * slope_1;
if (value > range_1)
value = 127;
table[i] = 0;
}
for (i = 0; i < 2048; i++)
{
if (i < zeroes_0)
value = 0;
else
value = (zeroes_0 - i) * slope_0;
if (value < -range_0)
value = -127;
table[4096 - i] = value;
}
}
For an array of 4096 elements, 4095 is the largest valid index you can use. The statement table[4096 - i] = value; writes to table[4096] when i==0, which is outside the bounds of table.
Presumably you meant to do table[4095 - i] = value;, which will give you an index of 4095..2048.
For completeness, so this question doesn't remain in the unanswered section, you are writing out of bounds on the last line of your program in the for loop:
for (i = 0; i < 2048; i++)
{
if (i < zeroes_0)
value = 0;
else
value = (zeroes_0 - i) * slope_0;
if (value < -range_0)
value = -127;
table[4096 - i] = value; // out of bounds when i = 0.
}
This is causing the windows equivalent of a seg fault aka access violation. You would notice this on unix too if you ran it under valgrind.
As it turned out it was a segmentation fault, I had table[4096 - i] = value; which would be out of the array's bounds when i was equal to 0.
Sometimes when you focus too much on a part of the code you thought was not working you forget to check the part you thought was working.

How to convert byte to int?

I have an Arduino which is reading in a set of three bytes from a program which correspond to degrees in which an actuator must turn. I need to convert these bytes into integers so I can pass those integers on to my actuators.
For example, I know the default rest state value I receive from the program is 127. I wrote a C# program to interpret these bytes and that can get them to a single integer value. However, I am unable to figure out how to do this in the Arduino environment with C. I have tried typecasting each byte to a char and storing that in a string. However that returns garbled values that make no sense.
void loop() {
if(Serial.available() && sw)
{
for(int j = 0; j < 3; j++)
{
input[j] = Serial.read();
}
//command = ((String)input).toInt();
sw = 0;
}
String myString = String((char *)input);
Serial.println(myString);
}
The return value of Serial.read() is an int. Therefore, if you have the following code snippet:
int input[3];
for (int i = 0; i < 3; i++) {
input[i] = Serial.read();
}
Then input should store three ints. However, the code:
char* input[3];
for (int i = 0; i < 3; i++) {
input[i] = Serial.read();
}
Will just store the byte conversion from int to char.
If you want to store this as a string, you need to do a proper conversion. In this case, use itoa (see Arduino API description).
The code snippet would be:
#include <stdlib>
char* convertedString = itoa(input[i]);
This should work:
int command = input[0]*256*256 + input[1]*256 + input[2];
By the way the default language you use to program your an Arduino is C++, not C. Although they have some similarities.
Below logic will help you
iDst = (cSrc[0] << 16) | (cSrc[1] << 8) | cSrc[2]
or else you can use union for this case
union byte2char
{
char c[4];
int i;
};
But union implementation needs to consider little and big endian systems

Access 2D Pointer-Array

I have 4 arrays and each has different amount of entries. All these arrays are collected in another one. It's implemented like this:
Code in a c library
static const int32_t ONE_COLOR[2] = { RGB_BLACK, RGB_WHITE };
static const int32_t TWO_COLOR[4] = { RGB_WHITE, RGB_RED, RGB_GREEN, RGB_BLUE };
static const int32_t THREE_COLOR[8] = { RGB_BLACK, RGB_RED, RGB_GREEN, RGB_BLUE,
RGB_CYAN, RGB_YELLOW, RGB_MAGENTA, RGB_WHITE };
static const int32_t FOUR_COLOR[16] = { RGB_WHITE, RGB_RED, RGB_GREEN, RGB_BLUE,
RGB_CYAN, RGB_YELLOW, RGB_MAGENTA, RGB_DARK_RED, RGB_DARK_GREEN,
RGB_DARK_BLUE, RGB_LIGHT_BLUE, RGB_LIGHT_GREEN, RGB_ORANGE, RGB_LIME,
RGB_PINK, RGB_LILA };
static const int32_t* COLOR_ARRAY[4] = { ONE_COLOR, TWO_COLOR, THREE_COLOR,
FOUR_COLOR };
How can I access COLOR_ARRAY[1][2] for example?
Thanks for your help :)
Edit
Example code for access:
Code for Arduino
for (i = 0; i < colorsLen; i++) {
n = 0;
for (j = 0; j < colorsWrite; j++) {
if (bitArray[i * colorsWrite + j] == 1) {
n |= 1 << (colorsWrite - 1 - j);
}
}
colors[i] = COLOR_ARRAY[colorsWrite - 1][n];
// testing access
// colors[i] = ONE_COLOR[n];
// colors[i] = n;
}
colorsLen is the length of the array colors and colorsWrite is the amount of bits that can be transmitted with one color.
The purpose is to transmit data via light from a smartphone to an arduino and back. To get more bandwith the data is coded with colors. colorsWrite defines how big colorsLen should be to get all data transmitted.
Well, judging from your question, you access COLOR_ARRAY[1][2] just like that. So the [1] in that expression is: TWO_COLOR[], and the [2] is: RGB_GREEN. So you do access an array as you did.
I.e: const COLOR clr = COLOR_ARRAY[1][2];
I might be missing some part of your question, but I hope it helps or clarifies.
Regards,
Øyvind
EDIT
This answer might give you a pointer
Defining a static array into a C or C++ source file
this line:
n |= 1 << (colorsWrite - 1 - j);
n will be at least 1, because 1<<0 = 1 ... you are using n as index to ONE_COLOR[n] so you cant access the color at index zero which is RGB_BLACK.

Resources