Related
I am working with Esspresif ESP32 WROOM board. I have tried to analyse the error I get with GDB Hardware Debugger, but I only receive the line where the error occurs, no error description.
Here's my small program:
typedef unsigned char u08;
void app_main() {
static char *mac_str = "00:00:00:00:00:00";
static u08 mac_addr[6] = {0x1a, 0x11, 0xaf, 0xa0, 0x47, 0x11};
net_dump_mac(mac_addr);
}
void net_dump_mac(const u08 *in) {
int pos = 0;
for (int i=0; i<6; i++) {
byte_to_hex(in[i], (u08 *)(mac_str+pos));
pos += 3;
}
uart_send(mac_str);
}
void byte_to_hex(u08 in, u08 *out) {
out[0] = nibble_to_hex(in >> 4); // <= crash occurs here !
out[1] = nibble_to_hex(in & 0xf);
}
u08 nibble_to_hex(u08 in) {
if (in < 10)
return '0' + in;
else
return 'A' + in - 10;
}
Some idea what am I doing wrong here?
char *mac_str = "00:00:00:00:00:00"; assigns a literal string to mac_str. A literal is read-only on many architectures. Trying to modify it will result in the memory manager no allowing it, often causing a segfault or other exception to occur.
Instead, do:
char mac_str[] = "00:00:00:00:00:00";
This creates an array that is initialized with the literal on the right, which gets copied to your array. The array will be the size of the literal string, including the null terminator. This array variable is modifyable.
I am working on a C module in micropython... if I pass a byte array to a function, only the first 8 bytes make it (according to sizeof). I have to also send in the length, then copy it to access everything in a function.
static void printSomeBytes(char *description, byte *bytes)
{
printf("\r\n%s: ", description);
for (int i = 0; i < sizeof(bytes); ++i )
{
printf("%02X", bytes[i]);
}
}
static void printAllBytes(char *description, byte *bytes, int length)
{
byte copy[length];
memcpy(copy, bytes, length);
printf("\r\n%s: ", description);
for (int i = 0; i < sizeof(copy); ++i )
{
printf("%02X", copy[i]);
}
// this also works without making a copy
//for (int i = 0; i < length; ++i )
//{
// printf("%02X", bytes[i]);
//}
}
byte Kifd[] = { 0x0B, 0x79, 0x52, 0x40, 0xCB, 0x70, 0x49, 0xB0, 0x1C, 0x19, 0xB3, 0x3E, 0x32, 0x80, 0x4F, 0x0B};
printSomeBytes("Kifd", kifd); // prints "Kifd: 0B795240CB7049B0"
printAllBytes("Kifd", kifd, sizeof(kifd)); // prints "Kifd: 0B795240CB7049B01C19B33E32804F0B"
What am I doing wrong / is there a better way to send a pointer to a byte array to a function?
sizeof(bytes) returns you the number of bytes that a pointer to byte will need to be stored in memory. It doesn't return you the number of bytes that the array pointed to by bytes contains.
For that you need to pass that size to the function:
static void printSomeBytes(char *description, byte *bytes, size_t size)
{
printf("\r\n%s: ", description);
for (size_t i = 0; i < size; ++i )
{
printf("%02X", bytes[i]);
}
puts("");
}
edit
I also added puts("") there so that the bytes are printed right away. Note
that printf is buffered and it won't show the output on the screen unless you flush it
(fflush(stdout);) by hand or add a '\n' newline at the end of printf.
puts(string) is equivalent to printf("%s\n", string); but without the
overhead of having to parse the format argument.
end edit
And then call it:
byte Kifd[] = { 0x0B, 0x79, 0x52, 0x40, 0xCB, 0x70, 0x49, 0xB0, 0x1C, 0x19, 0xB3, 0x3E, 0x32, 0x80, 0x4F, 0x0B};
printSomeBytes("Kifd", Kifd, sizeof Kifd / sizeof *Kifd);
Also the correct way of getting the number of elements of an array is:
sizeof array / sizeof *array
I encourage you to use that formula even when you know that the type is 8bit
long. It makes the code more portable.
You've done a poor job of explaining the issue. Are you saying that sizeof(bytes) returns 8?
bytes is a pointer, and sizeof(bytes) is returning the size of that pointer. And pointers may be 8 bytes on your system. That has nothing to do with the number of bytes at the address it points to.
In C, when you get a pointer, there is no way to know how many bytes it points to unless you provide that information as another argument or have a special terminating value in the data.
I have a program which takes the input data as a plaintext and then decrypts the message using 3DES method in CBC mode. But the values are hardcoded in the program I want to provide the encrypted value myself which should be decryted. How can I do this in the following program?
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int len;
DES_cblock key;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_cblock ivsetup = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_key_schedule keysched;
DES_cblock ivec;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key);
DES_set_odd_parity(&key);
if (DES_set_key_checked((C_Block *)key, &keysched))
{
fprintf(stderr, "ERROR: Unable to set key schedule\n");
exit(1);
}
/* 64 bytes of plaintext */
/* From here, encryption starts for the plaintext below. */
strcpy(in, "Now is the time for all men to stand up and be counted");
printf("Plaintext: [%s]\n", in);
len = strlen(in);
memcpy(ivec, ivsetup, sizeof(ivsetup));
DES_ncbc_encrypt(in, out, len, &keysched, &ivec, DES_ENCRYPT);
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e++);
printf("\n");
/* Till here, encryption is over. After this we have to decrypt
* the value which has been encoded, but I want to remove all this
* part and to provide my own encrypted message, and get the
* proper output.
*/
memcpy(ivec, ivsetup, sizeof(ivsetup));
/* The problem I am facing is how to provide the value properly
* to the parameter "out" and "keysched", which should be of my
* choice. For "out" I want to provide THIS value:
* "2DC39619B4450A8C27A3976C50DE5799".
*/
DES_ncbc_encrypt(out, back, len, &keysched, &ivec, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
Read more: http://blog.fpmurphy.com/2010/04/openssl-des-api.html#ixzz1uqOp1Yhv
Read C FAQ 20.10. Hexadecimal is a representation. All numbers are stored in binary internally. Your DES_cblock is probably a typedef for an (unsigned, perhaps!) integral type. So, what you have in effect is an array of integers. You can put numbers in decimal, hexadecimal or binary -- but they will all work. Hexadecimal is typically used in cryptography because it has some notational advantages.
I got it done.
I did it in a childish way for the time being but it is working now. I did it like this.
out[0]=0xA0; out[1]=0x69; out[2]=0x57; out[3]=0x3B;
out[4]=0x70; out[5]=0x26; out[6]=0x1C; out[7]=0xE8;
out[8]=0xEF; out[9]=0xF2; out[10]=0x9F;out[11]=0x60;
out[12]=0x80;out[13]=0x60;out[14]=0xB2;out[15]=0xE5;
Later I will do this thing in a for loop.
Create a dump function like this:
hexdump(char *buff, int len) {
int i,tmp;
for(i=0; i < len; i++) {
tmp = buff[i] & 0xff; /** to avoid sign extension */
printf("%02x",tmp);
}
}
And use it.
hexdump(back,len);
If you have to write it in memory, you can use sprintf, but you may have to write your own binary to hex function.
Using the nonstandard itoa function that stores the value it as a string, you can do the following:
char* hexstr = itoa(back,16);
// print out a string
printf("Decrypted Text: [%X]\n", back);
I have a C-array that looks like this:
char hexc[] = {
0x41, 0x80, 0x7a, 0x39, 0xea, 0x7e, 0x27, 0xfc,
0xe6, 0x45, 0x9c, 0x8b, 0xb5, 0xce, 0xa7, 0x35,
0x5f, 0xf2, 0x43, 0xcf, 0x89, 0xd8, 0x61, 0xec,
0xe7, 0xed, 0x2e, 0x34, 0x45, 0x0c, 0x32, 0xae,
0x71, 0x4f, 0x1c, 0xd8, 0xb5, 0x8c, 0x1e, 0xdd,
0x5d, 0x90, 0xf3, 0xf2, 0xe7, 0xa6, 0x4f, 0xef,
0xec, 0x96, 0xe3, 0xca, 0x8e, 0xeb, 0x64, 0x1d,
0x18, 0xa9, 0x95, 0xec, 0x64, 0x02, 0xf8, 0x26,
};
I knew that behind this hex-representations is a .GIF-file, what is the best way to generate from this hex-values a viewable file again? And how to add the missing GIF-header?
You would just open the file and write to it:
FILE *f = fopen("filename.gif", "wb");
if (!f) return; // or do something else
fwrite(hexc, 1, sizeof(hexc), f);
fclose(f);
Make sure to #include <stdio.h>.
open the file as binary
ofstream outfile ("new.gif",ofstream::binary);
and then write your buffer
outfile.write (hexc, sizeof hexc);
Turbo C DOS code
/****************************************************************************
** This support Compuserve 256 colour GIF87a and GIF89a image up to **
** 320x200 in size. **
****************************************************************************/
//This program requires a stack of at least 19.5K!!
#include "stdio.h"
typedef
struct GIFHeader {
char Signature [7];
unsigned int ScreenWidth, ScreenHeight;
unsigned char Depth, Background, Zero;
};
struct GIFDescriptor {
char Separator;
unsigned int ImageLeft, ImageTop, ImageWidth, ImageHeight;
unsigned char Depth;
};
char far *Screen = (char far *)0xA0000000L;
//For loading from the file
FILE *GIFFile;
unsigned int BPointer;
unsigned char Buffer [257];
//GIF data is stored in blocks of a certain size
unsigned char BlockSize;
//For loading the code
unsigned char CodeSize;
char BitsIn;
unsigned char Temp;
//Coordinates
unsigned int X, Y, tlX, tlY, brX, brY;
//The string table
unsigned int Prefix [4096];
unsigned char Suffix [4096];
//This sets the display to VGA 320x200 in 256 colours
void VGAScreen ()
{
asm {
mov ax, 0x13
int 0x10
}
}
//This resets the display to text mode
void TextScreen ()
{
asm {
mov ax, 0x3
int 0x10
}
}
//This sets a DAC register to a specific Red Green Blue-value
void SetDAC(unsigned char DAC, unsigned char R, unsigned char G, unsigned char B)
{
outportb (0x3C8, DAC);
outportb (0x3C9, R);
outportb (0x3C9, G);
outportb (0x3C9, B);
}
//This sets one pixel on the screen
void PutPixel (unsigned int x, unsigned int y, unsigned char c)
{
Screen [(y << 8) + (y << 6) + x] = c;
}
//Function to read from the buffer
unsigned char LoadByte ()
{
//Read next block}
if (BPointer == BlockSize) {
fread (Buffer, BlockSize + 1, 1, GIFFile);
BPointer = 0;
}
//Return byte
return Buffer [BPointer++];
}
//Procedure to read the next code from the file
unsigned int ReadCode ()
{
int Counter;
unsigned int Code;
Code = 0;
//Read the code, bit by bit
for (Counter = 0; Counter < CodeSize; Counter++) {
//Maybe, a new byte needs to be loaded with a further 8 bits
if (++BitsIn == 9) {
Temp = LoadByte ();
BitsIn = 1;
}
//Add the current bit to the code
if (Temp & 1) Code += 1 << Counter;
Temp >>= 1;
}
return Code;
}
//Procedure to draw a pixel
void NextPixel (unsigned int c)
{
//Actually draw the pixel on screen
PutPixel (X, Y, c & 255);
//Move to next row, if necessary
if (++X == brX) {
X = tlX;
Y++;
}
}
//Local function to output a string. Returns the first character.
unsigned char OutString (unsigned int CurCode)
{
unsigned int OutCount;
unsigned char OutCode [1024];
//If it's a single character, output that
if (CurCode < 256) {
NextPixel (CurCode);
} else {
OutCount = 0;
//Store the string, which ends up in reverse order
do {
OutCode [OutCount++] = Suffix [CurCode];
CurCode = Prefix [CurCode];
} while (CurCode > 255);
//Add the last character
OutCode [OutCount++] = CurCode;
//Output all the string, in the correct order
do {
NextPixel (OutCode [--OutCount]);
} while (OutCount);
}
//Return 1st character
return CurCode;
}
//This actually loads the GIF
void LoadGIF (char *Filename)
{
//For loading from the GIF file
struct GIFHeader Header;
struct GIFDescriptor Descriptor;
//Colour information
unsigned char BitsPerPixel,
NumOfColours;
unsigned int DAC;
unsigned char Palette [256][3];
//For indexing the string table
unsigned int FirstFree, FreeCode;
//All the code information
unsigned char InitCodeSize;
unsigned int Code, OldCode, MaxCode;
//Special codes
unsigned int ClearCode, EOICode;
//Check whether the GIF file exists, and open it
GIFFile = fopen (Filename, "rb");
if (GIFFile == 0) {
TextScreen ();
printf ("Could not open file %s", Filename);
return;
}
//Read header
fread (&Header, 6, 1, GIFFile);
Header.Signature [6] = 0;
fread (&Header.ScreenWidth, sizeof (Header) - 7, 1, GIFFile);
//Check signature and terminator
if ((strcmp (Header.Signature, "GIF87a")
&& strcmp (Header.Signature, "GIF89a"))
|| Header.Zero) {
TextScreen ();
printf ("Not a valid GIF file\n");
return;
}
//Get amount of colours in image
BitsPerPixel = 1 + (Header.Depth & 7);
NumOfColours = (1 << BitsPerPixel) - 1;
//Load global colour map
fread (Palette, 3, (NumOfColours + 1), GIFFile);
for (DAC = 0; DAC <= NumOfColours; DAC++)
SetDAC (DAC, Palette [DAC][0] >> 2,
Palette [DAC][1] >> 2,
Palette [DAC][2] >> 2);
//Load the image descriptor
fread (&Descriptor, sizeof (Descriptor), 1, GIFFile);
if (Descriptor.Separator != ',') {
TextScreen ();
printf ("Incorrect image descriptor.\n");
return;
}
//Get image corner coordinates
tlX = Descriptor.ImageLeft;
tlY = Descriptor.ImageTop;
brX = tlX + Descriptor.ImageWidth;
brY = tlY + Descriptor.ImageHeight;
//Some restrictions apply
if (Descriptor.Depth & 128) {
TextScreen ();
printf ("Local colour maps not supported\n");
return;
}
if (Descriptor.Depth & 64) {
TextScreen ();
printf ("Interlaced images not supported\n");
return;
}
//Get initial code size
fread (&CodeSize, 1, 1, GIFFile);
//GIF data is stored in blocks, so it's necessary to know the size
fread (&BlockSize, 1, 1, GIFFile);
//Start loader
BPointer = BlockSize;
//Special codes used in the GIF spec
ClearCode = 1 << CodeSize; //Code to reset
EOICode = ClearCode + 1; //End of file
//Initialize the string table
FirstFree = ClearCode + 2; //Strings start here
FreeCode = FirstFree; //Strings can be added here
//Initial size of the code and its maximum value
InitCodeSize = ++CodeSize;
MaxCode = 1 << CodeSize;
BitsIn = 8;
//Start at top left of image
X = Descriptor.ImageLeft;
Y = Descriptor.ImageTop;
do {
//Read next code
Code = ReadCode ();
//If it's an End-Of-Information code, stop processing
if (Code == EOICode) break;
//If it's a clear code...
else if (Code == ClearCode) {
//Clear the string table
FreeCode = FirstFree;
//Set the code size to initial values
CodeSize = InitCodeSize;
MaxCode = 1 << CodeSize;
//The next code may be read
Code = ReadCode ();
OldCode = Code;
//Set pixel
NextPixel (Code);
//Other codes
} else {
/*If the code is already in the string table, it's string is displayed,
and the old string followed by the new string's first character is
added to the string table.*/
if (Code < FreeCode)
Suffix [FreeCode] = OutString (Code);
else {
/*If it is not already in the string table, the old string followed by
the old string's first character is added to the string table and
displayed.*/
Suffix [FreeCode] = OutString (OldCode);
NextPixel (Suffix [FreeCode]);
}
//Finish adding to string table
Prefix [FreeCode++] = OldCode;
//If the code size needs to be adjusted, do so
if (FreeCode >= MaxCode && CodeSize < 12) {
CodeSize++;
MaxCode <<= 1;
}
//The current code is now old
OldCode = Code;
}
} while (Code != EOICode);
//Close the GIF file
fclose (GIFFile);
}
void main (int argcount, char *argvalue[])
{
char FileName [80];
//Check if a filename was passed as a parameter, otherwise ask for one
if (argcount > 1) {
strcpy (FileName, argvalue [1]);
} else {
printf ("Enter filename:");
gets (FileName);
}
//Switch to graphics screen
VGAScreen ();
//Load GIF file
LoadGIF (FileName);
//Wait for keypress
getch ();
//Switch back to text mode
TextScreen ();
}
Executive summary:
How can I define an arbitrarily-sized 2D array in C?
How can I determine the dimensions of that array at compile-time?
Full disclosure:
I'm writing code for an embedded controller. My application requires several lookup tables with different sizes which will all be used by one lookup function (a binary search). Here is what I have so far:
typedef struct
{
unsigned char count; // number of rows in the table
unsigned char width; // number of bytes in each row
const unsigned char * data; // pointer to table data[count][width]
}
LookupTable;
// returns the index of a value from within a table
unsigned char Lookup(unsigned long value, const LookupTable * table);
This part is working. What I would like to do now is define these tables in my source without having to manually enter the count and width constants. Here is what I am doing now:
#define T1_count 100
#define T1_width 3
const unsigned char table1_data[T1_count][T1_width] =
{
{ 0x12, 0x34, 0x56 },
{ 0x12, 0x38, 0x12 },
...
};
const LookupTable table1 = { T1_count, T1_width, table1_data };
Here is what I would like to be able to do (pseudo-code, since this array definition will not actually compile):
const unsigned char table1_data[] =
{
{ 0x12, 0x34, 0x56 },
{ 0x12, 0x38, 0x12 },
...
};
const LookupTable table1 =
{
get_count_expr(table1_data),
get_width_expr(table1_data),
table1_data
};
Obviously, get_count_expr and get_width_expr would have to be constant expressions of some sort, based on the size of the table, and not actual function calls.
To be clear, no part of this design is cast in stone. I'm just posting what I have so far, in the hopes that my intent is clear. Any ideas for improvement would be appreciated.
The "why":
These tables will be changed often, and it would make maintenance easier if entries could be added and removed, or the width of a table changed without having to manually adjust the constants each time. Having to keep track of the sizes manually can be error-prone and violates DRY. I'm looking for a better way.
Hmmm ... you can leave the leftmost size to the compiler:
#define T1_WIDTH 3
const unsigned char table1_data[][T1_WIDTH] =
{
{ 0x12, 0x34, 0x56 },
{ 0x12, 0x38, 0x12 },
/* ... */
};
T1_count = sizeof table1_data / sizeof *table1_data;
T1_width = sizeof *table1_data;
Well, it's ugly as hell, but I think the only way to do it within the constraints you've listed is to include the data in a string, and than have initialization code parse the string and generate the table. Ideally you'd do that in a script rather than use C to do it, but if it has to be in C, it has to be in C..
Note that in no way do I claim the following to be production code, but it's just a proof of concept...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define datatable "\
{ 0x12, 0x34, 0x56 },\
{ 0x14, 0x36, 0x10 },\
{ 0x13, 0x37, 0x11 },\
{ 0x12, 0x38, 0x12 }"
typedef struct
{
unsigned char count; // number of rows in the table
unsigned char width; // number of bytes in each row
unsigned char **data; // pointer to table data[count][width]
}
LookupTable;
int parsedatatable(char *data, LookupTable **table) {
char *p, *sp, save;
unsigned char *tabledata;
int count = 0, width = 0;
unsigned int tmp;
int i,j;
/* find count */
p = strstr(data,"{");
while (p) {
p++;
p = strstr(p, "{");
count++;
}
/* find width */
p = strstr(data, "{");
p++;
sp = strstr(p, "}");
if (sp != NULL) {
save = *sp;
*sp = '\0';
}
while (p) {
p = strstr(p, ",");
width++;
if (p != NULL) p++;
}
if (sp != NULL) {
*sp = save;
}
printf("Count = %d, width = %d\n",count, width);
tabledata = (unsigned char *)malloc(width*count*sizeof(unsigned char));
*table = (LookupTable *)malloc(sizeof(LookupTable));
(*table)->data = (unsigned char **)malloc(count*sizeof(unsigned char*));
for (i=0; i<count; i++) {
(*table)->data[i] = &(tabledata[i*width]);
}
(*table)->count = count;
(*table)->width = width;
p = data;
for (i=0; i<count; i++) {
p = strstr(p,"{");
if (!p) {
fprintf(stderr,"Fail (a) reading in data!: %s\n",data);
free((*table)->data);
free(tabledata);
free(*table);
return -1;
}
p++;
for (j=0; j<width; j++) {
printf("Scanning <%s>, ",p);
sscanf(p,"%x",&tmp);
printf("got %d\n",tmp);
(*table)->data[i][j] = tmp;
p = strstr(p,",");
if (!p && j<width-1) {
fprintf(stderr,"Fail (b) reading in data!: %d, %d, %s\n",i,j,data);
free((*table)->data);
free(tabledata);
free(*table);
return -1;
}
p++;
}
}
return 0;
}
void printtable(LookupTable *table) {
unsigned char i,j;
for (i=0; i<table->count; i++) {
printf("{");
for (j=0; j<table->width; j++) {
printf("%x ",table->data[i][j]);
}
printf("}\n");
}
return;
}
int main(int argc, char **argv) {
char *data;
LookupTable *table;
data = (char *)malloc(strlen(datatable)+1);
strcpy(data,datatable);
parsedatatable(data,&table);
printtable(table);
return 0;
}
Well, but who fills these tables with data? I think that generated sources are better solution.
Define table1_data inside a header. You can auto-generate that header using a script. I do something similar to that for some of my projects. I have a CSV file with data and a Ruby or Python script that generates a header from it.