Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

printf the values of a macro

5 views
Skip to first unread message

idon...@email.com

unread,
Feb 9, 2010, 6:54:01 PM2/9/10
to
I'm having a problem figuring out how to printf the value of BD_ADDR
from this macro.

What I'm tring to do is get it to display a Bluetooth Address in the
format

"BD_ADDR = xx:xx:xx:xx:xx:xx"

Several people have told me that it's written wrong and breaks the
rules of C, but I did not write it, it's part of a bluetooth lib

I can't do anything about how it's written, I just want to printf the
value of BD_ADDR but I have never before worked with a stucture like
this.


Below is a snippet of the lib I'm trying to work with.


/*
* Copyright (c) 2003 EISLAB, Lulea University of Technology.
* All rights reserved.
*
* This file is part of the lwBT Bluetooth stack.
*
* Author: Conny Ohult <co...@sm.luth.se>
*
*/

#ifndef __BD_ADDR_H__
#define __BD_ADDR_H__

struct bd_addr {
u8 addr[6];
};

#define BD_ADDR_LEN 6

#define BD_ADDR_ANY (&(struct bd_addr){{0,0,0,0,0,0}})
#define BD_ADDR_LOCAL (&(struct bd_addr){{0,0,0,0xff,0xff,0xff}})

#define BD_ADDR(bdaddr, a, b, c, d, e, f) do{ \
(bdaddr)->addr[0] = a; \
(bdaddr)->addr[1] = b; \
(bdaddr)->addr[2] = c; \
(bdaddr)->addr[3] = d; \
(bdaddr)->addr[4] = e; \
(bdaddr)->addr[5] = f; }while(0)

Ersek, Laszlo

unread,
Feb 9, 2010, 7:28:34 PM2/9/10
to

> "BD_ADDR = xx:xx:xx:xx:xx:xx"

> struct bd_addr {
> u8 addr[6];
> };


int
print_bd_addr(FILE *f, const struct bd_addr *p)
{
return fprintf(f, "BD_ADDR = %02x:%02x:%02x:%02x:%02x:%02x",
(unsigned)p->addr[0], (unsigned)p->addr[1],
(unsigned)p->addr[2], (unsigned)p->addr[3],
(unsigned)p->addr[4], (unsigned)p->addr[5]
);
}

If this is what you want.

Cheers,
lacos

idon...@email.com

unread,
Feb 9, 2010, 8:02:56 PM2/9/10
to
On 10 Feb 2010 01:28:34 +0100, la...@ludens.elte.hu (Ersek, Laszlo)
wrote:


Hi lacos,

Thanks for the post.

Sorry for my ignorance, but wouyld I put this inside the lib I'm
including, or would I put this in my main.c ?

No matter where I put it, would I just:

int ret;
ret = print_bd_addr();

to use it?

As you can tell, I don't do a whole lot of c programming and this is
the first time I've had to use any type of structure/macro.

Thanks!
Jason

Ersek, Laszlo

unread,
Feb 9, 2010, 8:18:00 PM2/9/10
to
In article <c514n5hhtj10hej94...@4ax.com>, idon...@email.com writes:
> On 10 Feb 2010 01:28:34 +0100, la...@ludens.elte.hu (Ersek, Laszlo)
> wrote:
>
>>In article <4qs3n5hhdgtacqcgj...@4ax.com>, idon...@email.com writes:
>>
>>> "BD_ADDR = xx:xx:xx:xx:xx:xx"
>>
>>> struct bd_addr {
>>> u8 addr[6];
>>> };
>>
>>
>>int
>>print_bd_addr(FILE *f, const struct bd_addr *p)
>>{
>> return fprintf(f, "BD_ADDR = %02x:%02x:%02x:%02x:%02x:%02x",
>> (unsigned)p->addr[0], (unsigned)p->addr[1],
>> (unsigned)p->addr[2], (unsigned)p->addr[3],
>> (unsigned)p->addr[4], (unsigned)p->addr[5]
>> );
>>}

> No matter where I put it, would I just:


>
> int ret;
> ret = print_bd_addr();
>
> to use it?


Please describe what you're trying to achieve.

Cheers,
lacos

Message has been deleted
Message has been deleted

Ian Collins

unread,
Feb 9, 2010, 9:00:17 PM2/9/10
to
J wrote:
> An example of using Ersek's Function:

>
> int print_bd_addr(FILE *f, const struct bd_addr *p)
> {
> return fprintf(f,"BD_ADDR = %2x:%2x:%2x:%2x:%2x:%2x",
> (unsigned char)p->addr[0],(unsigned char)p->addr[1],
> (unsigned char)p->addr[2],(unsigned char)p->addr[3],
> (unsigned char)p->addr[4],(unsigned char)p->addr[5]
> );
> }

Why are you casting to unsigned char?

--
Ian Collins

Message has been deleted

idon...@email.com

unread,
Feb 9, 2010, 9:12:20 PM2/9/10
to
On 10 Feb 2010 02:18:00 +0100, la...@ludens.elte.hu (Ersek, Laszlo)
wrote:
...

>
>
>Please describe what you're trying to achieve.
>
>Cheers,
>lacos

Hi lacos,

OK here's my story.

I'm obviously a beginning c programmer; hence my probably explaining
this wrong, but here's my best shot.


I'm editing a main.c that I created that has an #include "bte.h"

bte.h has an include of #include "bd_addr.h"

Inside bd_addr.h is the BD_ADDR function that has the bluetooth
address the system found on boot-up.


The main.c program I am writting currently compiles OK, but I need to
exact one more piece of information that it has access to, the
bluetooth address of the attached device.

(The device is a remote controller for a video game (a wii remote))

I was able to get all of the bluetooth functions I'm after to work
just fine, but I need to add a feature where I press the "B" Button
and it will display the attached remote's BlueTooth address.

There are many other functions, such as button_pressed, battery level
and so on that I was able to display with little trouble, but when I
came across this...macro I guess it is... I got stuck.


So, in closing, what I want to do is be able to call one of the
built-in functions of bte_address.h and get the BlueTooth Address and
printf it on the screen.

Below are links to the two includes that are part of my main.c


http://pastie.org/817526 = the entire bte.h

http://pastie.org/817534 = the entire bd_addr.h

J

unread,
Feb 9, 2010, 9:20:12 PM2/9/10
to

int main(void)
{
FILE *file = fopen("output.txt","wb");
struct bd_addr *BD_ADDR;

BD_ADDR->addr[0] = 0xff;
BD_ADDR->addr[1] = 0xff;
BD_ADDR->addr[2] = 0xff;
BD_ADDR->addr[3] = 0xff;
BD_ADDR->addr[4] = 0xff;
BD_ADDR->addr[5] = 0xff;

printf_bd_addr(file,&BD_ADDR);
fclose(file);
return 0;

}
int print_bd_addr(FILE *f, const struct bd_addr *p)
{
return fprintf(f,"BD_ADDR = %2x:%2x:%2x:%2x:%2x:%2x",

(unsigned)p->addr[0],(unsigned)p->addr[1],
(unsigned)p->addr[2],(unsigned)p->addr[3],

idon...@email.com

unread,
Feb 9, 2010, 11:39:18 PM2/9/10
to
On Tue, 9 Feb 2010 18:20:12 -0800 (PST), J <seawort...@gmail.com>
wrote:


Thanks J,

I really appreciate your showing how this works... I would have never
figuered it out on my own.

I'm getting ready to give this a try.
One question though..

With my limited knowledge of, it looks like this is going to write the
value to a text file called output.txt ?

If so, what do I need to change to get it to just printf it to the
output window?


idon...@email.com

unread,
Feb 10, 2010, 12:08:39 AM2/10/10
to


Well, it compiles with a few warnings, so I must be getting closer...

main.c
l:/devkitPro/mrc/src/source/main.c: In function 'get_bt_info':
l:/devkitPro/mrc/src/source/main.c:359: warning: passing argument 2 of
'print_bd_addr' from incompatible pointer type
l:/devkitPro/mrc/src/source/main.c:283: note: expected 'const struct
bd_addr *' but argument is of type 'struct bd_addr **'
l:/devkitPro/mrc/src/source/main.c:288: warning: dereferencing pointer
'BD_ADDR.56' does break strict-aliasing rules
l:/devkitPro/mrc/src/source/main.c:288: warning: dereferencing pointer
'BD_ADDR.56' does break strict-aliasing rules
l:/devkitPro/mrc/src/source/main.c:287: warning: dereferencing pointer
'BD_ADDR.56' does break strict-aliasing rules
l:/devkitPro/mrc/src/source/main.c:287: warning: dereferencing pointer
'BD_ADDR.56' does break strict-aliasing rules
l:/devkitPro/mrc/src/source/main.c:286: warning: dereferencing pointer
'BD_ADDR.56' does break strict-aliasing rules
l:/devkitPro/mrc/src/source/main.c:286: warning: dereferencing pointer
'BD_ADDR.56' does break strict-aliasing rules
l:/devkitPro/mrc/src/source/main.c:359: note: initialized from here
tools.c
linking ... src.elf
output ... src.dol

> Process Exit Code: 0
> Time Taken: 00:17

Ben Bacarisse

unread,
Feb 10, 2010, 7:49:58 AM2/10/10
to
idon...@email.com writes:

<snip>


> Well, it compiles with a few warnings, so I must be getting closer...
>
> main.c
> l:/devkitPro/mrc/src/source/main.c: In function 'get_bt_info':
> l:/devkitPro/mrc/src/source/main.c:359: warning: passing argument 2 of
> 'print_bd_addr' from incompatible pointer type
> l:/devkitPro/mrc/src/source/main.c:283: note: expected 'const struct
> bd_addr *' but argument is of type 'struct bd_addr **'
> l:/devkitPro/mrc/src/source/main.c:288: warning: dereferencing pointer
> 'BD_ADDR.56' does break strict-aliasing rules

Some of these are very serious. You can't consider then to be "a few
warnings". It is in the nature of C that a very serious error can go
undetected by the compiler. To get a warning is a bonus, and they
would not be ignored unless you know that it is safe to do so.

--
Ben.

Ersek, Laszlo

unread,
Feb 10, 2010, 10:36:25 AM2/10/10
to

> I'm editing a main.c that I created that has an #include "bte.h"
>
> bte.h has an include of #include "bd_addr.h"
>
> Inside bd_addr.h is the BD_ADDR function that has the bluetooth
> address the system found on boot-up.

> http://pastie.org/817526 = the entire bte.h
>
> http://pastie.org/817534 = the entire bd_addr.h

BD_ADDR is a function-like macro defined in "bd_addr.h", and it doesn't
return the boot-up bluetooth address or some such -- it fills in a
programmer-supplied "struct bt_addr" object with the six
programmer-supplied octets. In other words, it's a convenience macro for
assigning a value to a "bluetooth address" object.


> So, in closing, what I want to do is be able to call one of the
> built-in functions of bte_address.h and get the BlueTooth Address and
> printf it on the screen.

I've never seen this library before, but from the structure declarations
and function declarations (prototypes) in "bte.h", I'd try something
like this:

#define MAXDEVICES 10u

/* Device identifier of the device we care about, or whatever. */
static const u8 mycod[] = { 0xAAu, 0xBBu, 0xCCu };

/*
Return value:
negative : device found, print error
0 : no device found / device not found
positive : device found and printed (no trailing newline)
*/
static int
print_it(void)
{
u8 max_cnt,
flush;
s32 inq_res;
struct inquiry_info info[MAXDEVICES];

/* Set up as appropriate, for example: */
max_cnt = MAXDEVICES;
flush = ...;

inq_res = bte_inquiry(info, max_cnt, flush);

/*
Check inq_res. I guess it returns the number of devices found,
or a negative value in case of error. If it succeeds, search for
the device you're interested in based on "cod" or whatever, and
print its address.
*/

if (0 < inq_res) {
unsigned devidx;

for (devidx = 0u; devidx < (unsigned)inq_res; ++devidx) {
if (0 == memcmp(info[devidx].cod, mycod, sizeof mycod)) {
const u8 *addr;

addr = info[devidx].bdaddr.addr;
return fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned)addr[0], (unsigned)addr[1], (unsigned)addr[2],
(unsigned)addr[3], (unsigned)addr[4], (unsigned)addr[5]);
}
}
}

return 0;
}

As mentioned above, print_it() doesn't print a trailing newline after
the address. It doesn't flush stdout either. (I'm not even sure if
you've meant the standard output stream by "printing to the screen".)

Cheers,
lacos

Flash Gordon

unread,
Feb 10, 2010, 2:34:46 PM2/10/10
to
idon...@email.com wrote:
> I'm having a problem figuring out how to printf the value of BD_ADDR
> from this macro.
>
> What I'm tring to do is get it to display a Bluetooth Address in the
> format
>
> "BD_ADDR = xx:xx:xx:xx:xx:xx"
>
> Several people have told me that it's written wrong and breaks the
> rules of C, but I did not write it, it's part of a bluetooth lib

Sometimes there are good reasons for non-portable libraries to do
strange things. I'm not going to look look at the details...

> I can't do anything about how it's written, I just want to printf the
> value of BD_ADDR but I have never before worked with a stucture like
> this.

You just deal with the individual components rather than doing the thing
as a whole.

> Below is a snippet of the lib I'm trying to work with.

<snip>

> struct bd_addr {
> u8 addr[6];
> };

<snip>

Depends on how you are using this. If you have something like...

struct bd_addr myaddr;

You can access the elements as
myaddr.addr[0]
etc.

Then you can print them as normal and put in the colons yourself.
Remember that u8 is probably a typedef for "unsigned char" so you need
to select your format specifiers appropriately.
--
Flash Gordon

idon...@email.com

unread,
Feb 10, 2010, 3:25:44 PM2/10/10
to

Hello lacos,

Thank you so much for all of your help.
I will try this tonight when I get home from school.
Even if I can't get this to work, you helped me try!

On a side note�It's reassuring to find out there are still people that
offer assistance to us newbs just starting out.

Is there any way I can repay you for assisting me, like maybe a small
donation to your favorite charity? ... Or maybe $10.00 to the Haiti
Earthquake Relief Fund?

I know your time is worth much more than $10.00, but I'm on small
budget :)

On 10 Feb 2010 16:36:25 +0100, la...@ludens.elte.hu (Ersek, Laszlo)
wrote:

>In article <te34n556tav479lc8...@4ax.com>, idon...@email.com writes:

Ersek, Laszlo

unread,
Feb 10, 2010, 4:44:33 PM2/10/10
to
(Off-topic, sorry.)

> Is there any way I can repay you for assisting me,

C'mon, don't kid me; you try to give back the help you've received from
people to other people. It's always better to try to assist in public so
that others can catch incidental (or deliberate) errors.


> like maybe a small donation to your favorite charity? ... Or maybe
> $10.00 to the Haiti Earthquake Relief Fund?

If you consider doing that, please do that anyway; I don't come into the
picture.


> I know your time is worth much more than $10.00

Actually I'm more than compensated by you saying thanks.

Good luck,
lacos

0 new messages