Share pthread mutex between processes - process

I have this piece of code:
typedef struct
{
// ... other fields ...
pthread_mutex_t Lock;
} TShared;
const int NPROCESSES=32;
pid_t pidprocesses[128];
for (int i=0;i<NPROCESSES;i++)
{
pidprocesses[i]=fork();
if (!pidprocesses[i])
{
sleep(5); // wait the main process
int shmid = shmget(1616,sizeof(TShared),0666);
if (shmid<0)
{
printf("Error shmget!\n");
exit(0);
}
TShared *shm = (TShared *) shmat(shmid,NULL,0);
if (shm==-1)
{
printf("Error shmat!\n");
exit(0);
}
bool cond=true;
while(cond)
{
pthread_mutex_lock(&shm->Lock);
/* ... other code ... */
pthread_mutex_unlock(&shm->Lock);
}
exit(0);
}
}
// main process
int shmid = shmget(1616,sizeof(TShared),IPC_CREAT|0666);
if (shmid<0)
{
printf("Error shmget!\n");
exit(0);
}
TShared *shm = (TShared *) shmat(shmid,NULL,0);
if (shm==-1)
{
printf("Error shmat!\n");
exit(0);
}
pthread_mutex_init(&shm->Lock,NULL);
/* ... other code ... */
for (int i=0;i<NPROCESSES;i++) waitpid(pidprocesses[i],0,0);
This piece of code create 32 processes and then use shared memory with a pthread mutex to synchronize them and in the end the main process wait for the terminations of the childs.
Is this the correct way use a pthread mutex?

You must set the pshared attribute of the mutex to PTHREAD_PROCESS_SHARED if you want to do that:
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&shm->Lock, &attr);
pthread_mutexattr_destroy(&attr);

Related

Port not bound SystemC (E112)

I am trying to implement a producer (master) speaking to a memory element (slave) through the memory controller (which implements the interface simple_mem_interface).
Note: Some functions details and include statements are not fully mentioned in the code attached.
Searching for bugs in the code.
Adding debugging tools to find the fault in Write Enable Port.
binding.cpp
int sc_main(int argc, char* argv[])
{
sc_signal<unsigned int> d_out,d_in,address_d;
sc_signal<bool> wen, ren, ack;
sc_clock ClkFast("ClkFast", 100, SC_NS);
sc_clock ClkSlow("ClkSlow", 50, SC_NS);
Memory_Controller Controller1 ("Controller");
d_out = Controller1.data_mem_read;
ren.write(Controller1.REN);
ack.write(Controller1.ack);
d_in.write(Controller1.data_write);
address_d.write(Controller1.address);
wen.write(Controller1.WEN);
producer P1("Producer");
P1.out(Controller1);
P1.Clk(ClkFast);
Memory_module MEM("Memory");
MEM.Wen(wen);
MEM.Ren(ren);
MEM.ack(ack);
MEM.Clock(ClkSlow);
MEM.data_in(d_in);
MEM.data_out(d_out);
MEM.address(address_d);
sc_start(5000, SC_NS);
return 0;
Memory_controller.h
#define MEM_SIZE 100
#include <interface_func.h>
class Memory_Controller : public sc_module, public simple_mem_if
{
public:
// Ports
sc_in <unsigned int> data_mem_read{ "Data_Read_from_Memory" };
sc_out<bool> REN { "Read_Enable" };
sc_out<bool> WEN { "Write_Enable" };
sc_out <bool> ack{ "ACK_Bool" };
sc_out<unsigned int> address{ "Memory_Address" }, data_write{
"Data_Written_to_Memory" };
// constructor
Memory_Controller(sc_module_name nm) : sc_module(nm)
{ // Creating a 2 dimentional array holding adresses and data
WEN.write(false);
REN.write(false);
ack.write(false);
}
~Memory_Controller() //destructor
{
}
bool Write(unsigned int address_i, unsigned int datum) // blocking write
{
WEN.write(true);
REN.write(false);
data_write.write(datum);
address.write(address_i);
if (ack == true)
return true;
else
return false;
}
bool Read(unsigned int address_i, unsigned int& datum_i) // blocking read
{
WEN.write(false);
REN.write(true);
datum_i=data_mem_read;
address.write(address_i);
if (ack == true)
return true;
else
return false;
}
void register_port(sc_port_base& port, const char* if_typename)
{
cout << "binding " << port.name() << " to "
<< "interface: " << if_typename << endl;
}
};
Memory.h
#define MEM_SIZE 100
#include "interface_func.h"
class Memory_module : public sc_module
{
public:
sc_in<bool> Wen,Ren;
sc_in <unsigned int> address, data_in ;
sc_in<bool> Clock;
sc_out <unsigned int> data_out;
sc_out <bool> ack;
bool fileinput = false;
ifstream myfile;
unsigned int item [MEM_SIZE];
Memory_module()
{
}
void Write() // blocking write
{
while (true)
{
wait();
if (Wen==true)
{
if (address >= MEM_SIZE || address < 0)
{
ack=false;
}
else
{
item[address]=data_in;
ack=true;
}
}
}
}
void Read() // blocking read
{
while (true)
{
wait();
if (Ren)
{
if (address >= MEM_SIZE || address < 0)
ack=false;
else
{
data_out.write(item[address]);
ack=true;
}
}
}
}
SC_CTOR(Memory_module)
{
SC_THREAD(Read);
sensitive << Clock.pos();
SC_THREAD(Write);
sensitive << Clock.pos();
}
};
interface_func.h
class simple_mem_if : virtual public sc_interface
{
public:
virtual bool Write(unsigned int addr, unsigned int data) = 0;
virtual bool Read(unsigned int addr, unsigned int& data) = 0;
};
After debugging the SystemC binder.cpp code, the following error arises:
(E112) get interface failed: port is not bound : port 'Controller.Write_Enable' (sc_out)
You cannot drive your unconnected ports in the Memory_Controller constructor. If you want to explicitly drive these ports during startup, move these calls to a start_of_simulation callback:
Memory_Controller(sc_module_name nm) : sc_module(nm)
{}
void start_of_simulation()
{
WEN.write(false);
REN.write(false);
ack.write(false);
}

C++ Builder - program end error and localization error

I have a problem with a program I have done with Embarcadero C++ Builder.
Part one:
I want to make stand-alone .exe file, and according to that i have disabled "link with dynamic RTL" and disabled "link with runtime packages". But, every time i end my program, I get an error "Abnormal program termination". I've invstigated that and found a partial solution. When I enable link with runtime packages, that error does not appear, but .exe file won't run on PC which don't have C++ builder installed, because some .bpl files missing. So, for now, I have two possibilities: to have "Abnormal program termination" error, or not to have, functional .exe file for all PCs. Except for that error, my program works perfectly.
Part two:
I made fully functional program with 3 units, and I want to translate it on english language using resource DLL wizard. I can preview translated form, but I can't build it, because it say Error but I can't see any more details about error. I really don't know how is it possible to have working program with no errors, and localized version to have an error. I got the advice to do "clean all" and then "build all" but I can't even clean all because of that error.
I really don't know what to do anymore, I am struggling with those problems for a week now and I really hope that someone can help me. Thanks :)
Localization
Not sure if your localization tool is suited for Borland/Embarcadero apps (it might be just for MSVC++ apps which might be the problem).
I do localization on my own (as I needed custom stuff like internal messages and tables translation. So I coded a ~55 KByte parser that takes *.h,*.cpp,*.dfm of all windows as input and creates *.ini file and *.h that will read the selected language ini and translate all forms to it (Caption,Hint,...) then just for each new language I copy the ini and translate the strings. This way I can switch languages on the run without any DLL or restart needed and customers can add new languages on their own without the need for source code or programming skills.
Can not share the code however as it uses some non sharable (corporate) libs of mine for strings,dynamic lists and fast ini file access (they are included in the 55 KByte estimate) but I can share the executable (win32 standalone compiled in BDS2006 and for VCL BDS2006 formatting of code):
Form decode tool v2.70
Use the slow download (it is free without registration). I even add one window in the formulars for testing. You just run the exe and when done use the files from output. However the outputed source files use the fast ini file access (I can not share) so you would need to encode that (or replace with your style access). Here slow winapi based workaround for my ini.h that shoudl work:
#ifndef _ini_h
#define _ini_h
class inifile
{
public:
AnsiString section,filename;
// inline
inifile() {close();}
inifile(inifile& a) { *this=a; }
~inifile() {close();}
inifile* operator = (const inifile *a) { *this=*a; return this; }
//inifile* operator = (const inifile &a) { ...copy... return this; }
int open(AnsiString name) // open ini file
{
close();
if (FileExists(name)) { filename=name; return 1; }
return 0;
}
void close() // close ini file
{
filename="";
section="";
}
int sec_getid(const AnsiString &sec, bool _add) // select section to work with ignoring the returned ID
{
section=sec;
return 0;
}
AnsiString key_get(int section_id,const AnsiString &key,const AnsiString &def) // read key from section of ini with default value
{
if (filename=="") return def;
char dest[1024]; AnsiString val;
GetPrivateProfileString(section.c_str(),key.c_str(),def.c_str(),dest,1024,filename.c_str());
val=dest; return val;
}
};
#endif
So the app has 3 folders:
formulars
put all the *.h,*.cpp;*.dfm files of your forms here. The parsing of *.h is stopping on public: (skip user declarations) to prevent collisions with user code. You can also add comments to end of component line:
// LANGUAGE_SKIP_CAPT
// LANGUAGE_SKIP_TEXT
// LANGUAGE_SKIP_HINT
or any combination to prevent translation is messing with it.
messages
Ignore this it is for *.cpp source files with internal messages _messages[]to translate must be properly encoded using markers in comments like this:
AnsiString _messages[_msg_enum_end+1]=
{
// LANGUAGE_MSG000_TEXT_BEG
"Error: message id out of range !!!",
"OpenGL FBO support is missing !!! ... switching to simplified graphics",
"OpenGL VBO support is missing !!! ... switching to simplified graphics",
"Sorry: ATI graphic card detected !!! ... switching to simplified graphics",
"Sorry: ATI Radeon HD 5450 graphic card detected !!! ... disabling preview features",
"Done.",
// LANGUAGE_MSG000_TEXT_END
"",
""
};
output
the app here outputs 4 files
init.h can ignore this it is just init/exit load/stroing of window state
init.ini ini file for the init can ignore this
into app ini.
language.h this is what you want it is the translation routine
english.ini translation ini file using current window texts
Here example of generated language.h:
#include <math.h>
#include "ini.h" // use the ini.h above
void language_init(AnsiString name)
{
int sec;
inifile ini;
ini.open(name);
sec=ini.sec_getid("Twin_EditorSetup",true);
win_EditorSetup->ck_specchar->Caption=ini.key_get(sec,"C_ck_specchar","Special chars.");
win_EditorSetup->ck_specchar->Hint =ini.key_get(sec,"H_ck_specchar","View special characters on/off");
win_EditorSetup->cb_colors->Hint =ini.key_get(sec,"H_cb_colors","Select color for editing");
win_EditorSetup->ed_tabs->Text =ini.key_get(sec,"T_ed_tabs","1");
win_EditorSetup->ed_tabs->Hint =ini.key_get(sec,"H_ed_tabs","Tabulator size");
win_EditorSetup->ck_smart->Caption=ini.key_get(sec,"C_ck_smart","Smart eol");
win_EditorSetup->ck_smart->Hint =ini.key_get(sec,"H_ck_smart","Delete empty space at end of edited line");
win_EditorSetup->RadioGroup1->Caption=ini.key_get(sec,"C_RadioGroup1","");
win_EditorSetup->RadioGroup1->Hint =ini.key_get(sec,"H_RadioGroup1","");
win_EditorSetup->rb_eol1310->Caption=ini.key_get(sec,"C_rb_eol1310","CR LF");
win_EditorSetup->rb_eol1310->Hint =ini.key_get(sec,"H_rb_eol1310","EOL CR LF 13 10");
win_EditorSetup->rb_eol13->Caption=ini.key_get(sec,"C_rb_eol13","CR");
win_EditorSetup->rb_eol13->Hint =ini.key_get(sec,"H_rb_eol13","EOL CR 13");
win_EditorSetup->rb_eol10->Caption=ini.key_get(sec,"C_rb_eol10","LF");
win_EditorSetup->rb_eol10->Hint =ini.key_get(sec,"H_rb_eol10","EOL LF 10");
win_EditorSetup->txt_tabs->Caption=ini.key_get(sec,"C_txt_tabs","TAB:");
win_EditorSetup->txt_tabs->Hint =ini.key_get(sec,"H_txt_tabs","");
win_EditorSetup->pan_color->Caption=ini.key_get(sec,"C_pan_color","");
win_EditorSetup->pan_color->Hint =ini.key_get(sec,"H_pan_color","Pick color");
sec=ini.sec_getid("Global",true);
ini.close();
}
so in your main app form cpp include language.h but after its pointer is declared (after line like TForm1 *Form1; ) otherwise you will get access violation erros. Now call language_init with selected language ini file on any language change or Apps init like this:
if (Form1->Visible) language_init(ExtractFilePath(Application->ExeName)+"english.ini");
you need to specify full path if winapi is used for the ini.h !!!
Packages
Hard to say without MCVE. You most likely use non standard 3th party package and or have a bug in the code. My bet is you got memory leaks which tend to make a such errors time to time (especially on exit of app) try to use CodeGuard in the Project options which will show you runtime errors and allow you to debug them much better but it will not work for huge projects. Also if you are on older compiler or need to debug the memory leaks see these:
traceback a pointer in c++ code
BDS 2006 C++ hidden memory manager conflicts
They might solve your issues (even those you did not know of yet)
P.S.
If you're interested here is the main source for this tool (but without the supporting *.h files it will not work but you can see how it work in case you want to encode this on your own:
//--- Formular decoder storage class ver 2.40 -------------------------------
#ifndef _frm_decode_h
#define _frm_decode_h
//---------------------------------------------------------------------------
const int _frm_cmp_prop_none =0x00000000;
// language properties
const int _frm_cmp_prop_capt =0x00000001;
const int _frm_cmp_prop_text =0x00000002;
const int _frm_cmp_prop_hint =0x00000004;
// ini properties
const int _frm_cmp_prop_align =0x00010000;
const int _frm_cmp_prop_pos =0x00020000;
const int _frm_cmp_prop_check =0x00040000;
const int _frm_cmp_prop_down =0x00080000;
const int _frm_cmp_prop_page =0x00100000;
class _frm_component
{
public:
AnsiString name; // name in C++
int prop; // component class enum
int action; // if true do not save/load by language
};
_frm_component frm_component[]=
{
// standard
"TMenuItem" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_check,0,
"TLabel" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TEdit" ,_frm_cmp_prop_text|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TMemo" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TButton" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TCheckBox" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_check,0,
"TRadioButton" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_check,0,
"TListBox" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TComboBox" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TScrollBar" , _frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_pos ,0,
"TGroupBox" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TRadioGroup" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TPanel" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TAction" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
// additional
"TBitBtn" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TSpeedButton" ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_down ,0,
"TStringGrid" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TCategoryButtons" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
// win32
"TProgressBar" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
// system
"TPaintBox" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
// win3.1
"TTabbedNotebook" , _frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_page ,0,
"TFileListBox" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TDirectoryListBox" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"TDriveComboBox" , _frm_cmp_prop_hint|_frm_cmp_prop_align ,0,
"",0,0
};
//---------------------------------------------------------------------------
class frm_decode
{
public:
AnsiString form; // formular class name in C++
struct _component:_frm_component
{
// language properties
AnsiString text,hint;
// init properties
AnsiString align; // -only for internal init purposes
AnsiString checked,down,position,left,top,width,height;
int skip; // znacky
void reset()
{
text="";
hint="";
align="alNone";
checked="False";
down="False";
position="1";
left="0";
top="0";
width="1";
height="1";
skip=0;
}
};
struct _message { AnsiString id,txt; };
List<_component> cmp;
List<_message> msg;
frm_decode(){ reset(); }
void reset() { form=""; cmp.reset(); msg.reset(); }
void load_form(AnsiString file); // load formular (file.h, file.dfm)
void load_msg(AnsiString file); // load messages (file.h, file.cpp)
void save_lang_ini(inifile &ini); // save language to ini
void save_init_ini(inifile &ini); // save initialisation to ini
void save_lang_cpp(AnsiString &txt,bool end=true); // save language loader (C++) to txt
void save_init_cpp(AnsiString &txt,bool end=true); // save init loader (C++) to txt
void save_exit_cpp(AnsiString &txt,bool end=true); // save exit saver (C++) to txt
};
//---------------------------------------------------------------------------
void frm_decode::load_form(AnsiString file)
{
// nepodporuje "/* ... */"
int hnd,adr,siz,i,j,l,e,_skip;
AnsiString lin,s,s0,ss;
_component a;
BYTE *txt;
reset();
// load list of components from: file.h
hnd=FileOpen(file+".h",fmOpenRead);
if (hnd<0) return;
siz=FileSeek(hnd,0,2);
FileSeek(hnd,0,0);
txt=new BYTE[siz];
if (txt==NULL) { FileClose(hnd); return; }
FileRead(hnd,txt,siz);
FileClose(hnd);
for (adr=0;adr<siz;)
{
lin=txt_load_lin(txt,siz,adr,true);
l=lin.Length();
for (_skip=0;i<=l;) // osetri zacky este pred odrezanim pokecu
{
s=str_load_str(lin,i,true);
if (s=="LANGUAGE_SKIP_CAPT") _skip|=_frm_cmp_prop_capt;
if (s=="LANGUAGE_SKIP_TEXT") _skip|=_frm_cmp_prop_text;
if (s=="LANGUAGE_SKIP_HINT") _skip|=_frm_cmp_prop_hint;
}
if (str_is_mask(lin,"*//*")) { s=lin; lin=""; for (i=1;i<l;i++) if ((s[i]=='/')&&(s[i+1]=='/')) break; else lin+=char(s[i]); l=lin.Length(); }
s=""; s0=""; e=0;
for (i=1;i<=l;)
{
s0=s;
s=str_load_str(lin,i,true);
if (s=="private:") // stop processing for non formular symbols
{
adr=siz; break;
}
if (!e) { e=1; continue; }
if (s0=="class")
{
form=s;
continue;
}
if (s!="")
for (j=0;;j++)
{
if (frm_component[j].name=="") break;
if (frm_component[j].name==s0)
{
a.reset();
a.name="";
if (s[1]!='*') s=" "+s;
for (int q=2;q<=s.Length();q++) a.name+=s[q];
a.prop=frm_component[j].prop;
a.action=0;
a.skip=_skip;
cmp.add(a);
break;
}
}
}
}
delete txt;
// load component properties from: file.dfm
int cmpid=-1;
hnd=FileOpen(file+".dfm",fmOpenRead);
if (hnd<0) return;
siz=FileSeek(hnd,0,2);
FileSeek(hnd,0,0);
txt=new BYTE[siz];
if (txt==NULL) { FileClose(hnd); return; }
FileRead(hnd,txt,siz);
FileClose(hnd);
for (adr=0;adr<siz;)
{
lin=txt_load_lin(txt,siz,adr,true);
l=lin.Length();
for (i=1;i<=l;i++) // if cutted '' line then continue
if (lin[i]>32)
{
if (lin[i]!='\'') i=-1;
break;
}
if (i<0) { s=""; s0=""; e=0; } // else new line
for (i=1;i<=l;)
{
int q=1;
if (s!="")
if (s[1]=='\'')
{
if (s[s.Length()]!='\'')
{
s+=" "+str_load_str(lin,i,true);
if (s[s.Length()]!='\'') continue;
}
q=0;
}
if (q)
{
int qqq=0; // handle cutted '' line
ss=str_load_str(lin,i,true);
if ((s0!="")&&((ss!="")&&(ss[1]=='\''))) { qqq=1; s+=ss; }
if ((s0!="")&&(ss=="+")) { qqq=1; }
if (!qqq) { s0=s; s=ss; }
if (s!="")
if (s[1]=='\'')
if (s[s.Length()]!='\'')
e=0;
}
/* // odstran ''
if (s!="")
if (s[1]=='\'')
if (s[s.Length()]=='\'')
{ ss=""; for (q=2;q<s.Length();q++) ss+=s[q]; s=ss; }
*/
if (!e) { e=1; continue; }
if (s!="")
if (s0=="object")
{
cmpid=-1;
if (s[s.Length()]==':')
{
AnsiString t=s;
s=""; for (j=1;j<t.Length();j++) s+=char(t[j]);
}
for (j=0;j<cmp.num;j++)
if (cmp[j].name==s)
{
cmpid=j;
break;
}
continue;
}
if (cmpid<0) continue;
char aa;
bool tt;
int ii,cc,ll=s.Length();
if (ll>0)
{
ss="";
tt=false;
for (ii=1;ii<=ll;ii++)
{
aa=s[ii];
if (aa=='\'') { tt=!tt; continue; }
if (tt) { ss+=aa; continue; }
if (aa!='#'){ ss+=aa; continue; }
cc=0;
for (ii++;ii<=ll;ii++)
{
aa=s[ii];
if (aa=='\'') { ii--; break; }
if (aa< '0') { ii--; break; }
if (aa> '9') { ii--; break; }
cc*=10; cc+=aa-'0';
}
ss+=char(cc);
}
s=ss;
}
if (s0=="Action" ) cmp[cmpid].action=1;
if (s0=="Caption" ) cmp[cmpid].text=s;
if (s0=="Text" ) cmp[cmpid].text=s;
if (s0=="Hint" ) cmp[cmpid].hint=s;
if (s0=="Align" ) cmp[cmpid].align=s;
if (s0=="Checked" ) cmp[cmpid].checked=s;
if (s0=="Down" ) cmp[cmpid].down=s;
if (s0=="Position") cmp[cmpid].position=s;
if (s0=="Left" ) cmp[cmpid].left=s;
if (s0=="Top" ) cmp[cmpid].top=s;
if (s0=="Width" ) cmp[cmpid].width=s;
if (s0=="Height" ) cmp[cmpid].height=s;
}
}
delete txt;
// load list of messages from: file.cpp
load_msg(file+".cpp");
}
//---------------------------------------------------------------------------
void frm_decode::load_msg(AnsiString file)
{
// nepodporuje "/* ... */"
int hnd,adr,siz,i,l,e;
AnsiString lin,s;
BYTE *txt;
hnd=FileOpen(file,fmOpenRead);
if (hnd<0) return;
siz=FileSeek(hnd,0,2);
FileSeek(hnd,0,0);
txt=new BYTE[siz];
if (txt==NULL) { FileClose(hnd); return; }
FileRead(hnd,txt,siz);
FileClose(hnd);
e=msg.num;
for (adr=0;adr<siz;)
{
lin=txt_load_lin(txt,siz,adr,true);
l=lin.Length();
for (i=1;i<=l;)
{
s=str_load_str(lin,i,true);
if (s=="_msg_enum_beg")
for (;adr<siz;)
{
lin=txt_load_lin(txt,siz,adr,true);
l=lin.Length();
for (i=1;i<=l;)
{
s=str_load_str(lin,i,true);
if (s=="_msg_enum_end") { adr=siz; i=l+1; break; }
if (str_is_mask(s,"_msg*"))
{
_message m;
m.id=s;
m.txt="";
msg.add(m);
}
}
}
}
}
for (adr=0;adr<siz;)
{
lin=txt_load_lin(txt,siz,adr,true);
l=lin.Length();
for (i=1;i<=l;)
{
s=str_load_str(lin,i,true);
if (s=="_messages[_msg_enum_end+1]")
for (;adr<siz;)
{
if (e>=msg.num) break;
s="";
for (;adr<siz;adr++)
if (txt[adr]=='"')
{
adr++;
for (;adr<siz;adr++)
if (txt[adr]=='"')
{
adr++;
msg[e].txt=s;
e++;
break;
}
else s+=char(txt[adr]);
break;
}
}
}
}
delete txt;
}
//---------------------------------------------------------------------------
void frm_decode::save_lang_ini(inifile &ini)
{
int i,p,s,sec;
AnsiString key,val;
sec=ini.sec_getid(form,true);
for (i=0;i<msg.num;i++) ini.key_set(sec,msg[i].id,msg[i].txt);
for (i=0;i<cmp.num;i++)
{
if (cmp[i].action) continue;
key=cmp[i].name;
p=cmp[i].prop;
s=cmp[i].skip;
if ((int(p&_frm_cmp_prop_capt)!=0)&&(int(s&_frm_cmp_prop_capt)==0)) ini.key_set(sec,"C_"+key,cmp[i].text);
if ((int(p&_frm_cmp_prop_text)!=0)&&(int(s&_frm_cmp_prop_text)==0)) ini.key_set(sec,"T_"+key,cmp[i].text);
if ((int(p&_frm_cmp_prop_hint)!=0)&&(int(s&_frm_cmp_prop_hint)==0)) ini.key_set(sec,"H_"+key,cmp[i].hint);
}
}
//---------------------------------------------------------------------------
void frm_decode::save_init_ini(inifile &ini)
{
int i,p,sec;
AnsiString key,val;
sec=ini.sec_getid(form,true);
for (i=0;i<cmp.num;i++)
{
if (cmp[i].action) continue;
key=cmp[i].name;
p=cmp[i].prop;
if (cmp[i].align=="alLeft") ini.key_set(sec,"XS_"+key,cmp[i].width);
if (cmp[i].align=="alRight") ini.key_set(sec,"XS_"+key,cmp[i].width);
if (cmp[i].align=="alTop") ini.key_set(sec,"YS_"+key,cmp[i].height);
if (cmp[i].align=="alBottom") ini.key_set(sec,"YS_"+key,cmp[i].height);
if (cmp[i].align=="alClient")
{
}
if (cmp[i].align=="alNone")
{
/*
ini.key_set(sec,"X0_"+key,cmp[i].left);
ini.key_set(sec,"Y0_"+key,cmp[i].top);
ini.key_set(sec,"XS_"+key,cmp[i].width);
ini.key_set(sec,"YS_"+key,cmp[i].height);
*/
}
if (int(p&_frm_cmp_prop_check )!=0) ini.key_set(sec,"CHK_"+key,(cmp[i].checked=="True")?"1":"0");
if (int(p&_frm_cmp_prop_down )!=0) ini.key_set(sec,"DWN_"+key,(cmp[i].down =="True")?"1":"0");
if (int(p&_frm_cmp_prop_pos )!=0) ini.key_set(sec,"POS_"+key, cmp[i].position );
}
}
//---------------------------------------------------------------------------
void frm_decode::save_lang_cpp(AnsiString &txt,bool end)
{
int i,p,s;
AnsiString cpp,lin,key,frm,tabl,endl;
tabl=char(9); endl=char(13); endl+=char(10);
cpp="";
if (txt=="")
{
lin="";
lin+="#include <math.h>"+endl;
lin+="#include \"ini.h\""+endl+endl;
lin+="void language_init(AnsiString name)"+endl;
lin+=tabl+"{"+endl;
lin+=tabl+"int sec;"+endl;
lin+=tabl+"inifile ini;"+endl;
lin+=tabl+"ini.open(name);"+endl;
cpp+=lin;
}
frm=""; for (i=2;i<=form.Length();i++) frm+=form[i];
cpp+=endl;
cpp+=tabl+"sec=ini.sec_getid(\""+form+"\",true);"+endl;
for (i=0;i<msg.num;i++)
{
lin=tabl+"_messages[";
if (i<100) lin+=" ";
if (i<10) lin+=" ";
lin+=i;
lin+="]=ini.key_get(sec,\""+msg[i].id+"\",\""+msg[i].txt+"\");"+endl;
cpp+=lin;
}
for (i=0;i<cmp.num;i++)
{
if (cmp[i].action) continue;
key=cmp[i].name;
p=cmp[i].prop;
s=cmp[i].skip;
lin="";
if ((int(p&_frm_cmp_prop_capt)!=0)&&(int(s&_frm_cmp_prop_capt)==0)) lin+=tabl+frm+"->"+key+"->Caption=ini.key_get(sec,\"C_"+key+"\",\""+cmp[i].text+"\");"+endl;
if ((int(p&_frm_cmp_prop_text)!=0)&&(int(s&_frm_cmp_prop_text)==0)) lin+=tabl+frm+"->"+key+"->Text =ini.key_get(sec,\"T_"+key+"\",\""+cmp[i].text+"\");"+endl;
if ((int(p&_frm_cmp_prop_hint)!=0)&&(int(s&_frm_cmp_prop_hint)==0)) lin+=tabl+frm+"->"+key+"->Hint =ini.key_get(sec,\"H_"+key+"\",\""+cmp[i].hint+"\");"+endl;
cpp+=lin;
}
if (end)
{
lin=endl;
lin+=tabl+"ini.close();"+endl;
lin+=tabl+"}"+endl;
cpp+=lin;
}
txt+=cpp;
}
//---------------------------------------------------------------------------
void frm_decode::save_init_cpp(AnsiString &txt,bool end)
{
int i,p;
AnsiString cpp,lin,key,frm,tabl,endl,endlx;
tabl=char(9); endl=char(13); endl+=char(10); endlx="\\"+endl;
cpp="";
if (txt=="")
{
lin="";
lin+="//---------------------------------------------------------------------------"+endl;
lin+="#include <math.h>"+endl;
lin+="#include \"ini.h\""+endl;
lin+="//---------------------------------------------------------------------------"+endl;
lin+="#define _def_program_init(name) for(;;)"+endlx;
lin+=tabl+"{"+endlx;
lin+=tabl+"int sec;"+endlx;
lin+=tabl+"inifile ini;"+endlx;
lin+=tabl+"ini.open(name);"+endlx;
// lin+=tabl+"if (!ini.open(name)) break;"+endlx;
cpp+=lin;
}
frm=""; for (i=2;i<=form.Length();i++) frm+=form[i];
cpp+=tabl+"sec=ini.sec_getid(\""+form+"\",true);"+endlx;
for (i=0;i<cmp.num;i++)
{
if (cmp[i].action) continue;
key=cmp[i].name;
p=cmp[i].prop;
lin="";
if (cmp[i].align=="alLeft") lin+=tabl+frm+"->"+key+"->Width =ini.key_geti(sec,\"XS_"+key+"\","+cmp[i].width +");"+endlx;
if (cmp[i].align=="alRight") lin+=tabl+frm+"->"+key+"->Width =ini.key_geti(sec,\"XS_"+key+"\","+cmp[i].width +");"+endlx;
if (cmp[i].align=="alTop") lin+=tabl+frm+"->"+key+"->Height=ini.key_geti(sec,\"YS_"+key+"\","+cmp[i].height+");"+endlx;
if (cmp[i].align=="alBottom") lin+=tabl+frm+"->"+key+"->Height=ini.key_geti(sec,\"YS_"+key+"\","+cmp[i].height+");"+endlx;
if (cmp[i].align=="alClient")
{
}
if (cmp[i].align=="alNone")
{
/*
lin+=tabl+frm+"->"+key+"->Left =ini.key_geti(sec,\"X0_"+key+"\","+cmp[i].left +");"+endlx;
lin+=tabl+frm+"->"+key+"->Top =ini.key_geti(sec,\"Y0_"+key+"\","+cmp[i].top +");"+endlx;
lin+=tabl+frm+"->"+key+"->Width =ini.key_geti(sec,\"XS_"+key+"\","+cmp[i].width +");"+endlx;
lin+=tabl+frm+"->"+key+"->Height=ini.key_geti(sec,\"YS_"+key+"\","+cmp[i].height+");"+endlx;
*/
}
if (int(p&_frm_cmp_prop_check )!=0) lin+=tabl+frm+"->"+key+"->Checked =ini.key_geti(sec,\"CHK_"+key+"\","+cmp[i].checked +");"+endlx;
if (int(p&_frm_cmp_prop_down )!=0) lin+=tabl+frm+"->"+key+"->Down =ini.key_geti(sec,\"DWN_"+key+"\","+cmp[i].down +");"+endlx;
if (int(p&_frm_cmp_prop_pos )!=0) lin+=tabl+frm+"->"+key+"->Position=ini.key_geti(sec,\"POS_"+key+"\","+cmp[i].position+");"+endlx;
cpp+=lin;
}
if (end)
{
lin+=tabl+"ini.close();"+endlx;
lin+=tabl+"break;"+endlx;
lin+=tabl+"}"+endl;
cpp+=lin;
}
txt+=cpp;
}
//---------------------------------------------------------------------------
void frm_decode::save_exit_cpp(AnsiString &txt,bool end)
{
int i,p;
AnsiString cpp,lin,key,frm,tabl,endl,endlx;
tabl=char(9); endl=char(13); endl+=char(10); endlx="\\"+endl;
cpp="";
if (txt=="")
{
lin+="//---------------------------------------------------------------------------"+endl;
lin+="#define _def_program_exit(name) for(;;)"+endlx;
lin+=tabl+"{"+endlx;
lin+=tabl+"int sec;"+endlx;
lin+=tabl+"inifile ini;"+endlx;
lin+=tabl+"ini.open(name);"+endlx;
cpp+=lin;
}
frm=""; for (i=2;i<=form.Length();i++) frm+=form[i];
cpp+=tabl+"sec=ini.sec_getid(\""+form+"\",true);"+endlx;
for (i=0;i<cmp.num;i++)
{
if (cmp[i].action) continue;
key=cmp[i].name;
p=cmp[i].prop;
lin="";
if (cmp[i].align=="alLeft") lin+=tabl+"ini.key_set(sec,\"XS_"+key+"\","+frm+"->"+key+"->Width );"+endlx;
if (cmp[i].align=="alRight") lin+=tabl+"ini.key_set(sec,\"XS_"+key+"\","+frm+"->"+key+"->Width );"+endlx;
if (cmp[i].align=="alTop") lin+=tabl+"ini.key_set(sec,\"YS_"+key+"\","+frm+"->"+key+"->Height);"+endlx;
if (cmp[i].align=="alBottom") lin+=tabl+"ini.key_set(sec,\"YS_"+key+"\","+frm+"->"+key+"->Height);"+endlx;
if (cmp[i].align=="alClient")
{
}
if (cmp[i].align=="alNone")
{
/*
lin+=tabl+"ini.key_set(sec,\"X0_"+key+"\","+frm+"->"+key+"->Left );"+endlx;
lin+=tabl+"ini.key_set(sec,\"Y0_"+key+"\","+frm+"->"+key+"->Top );"+endlx;
lin+=tabl+"ini.key_set(sec,\"XS_"+key+"\","+frm+"->"+key+"->Width );"+endlx;
lin+=tabl+"ini.key_set(sec,\"YS_"+key+"\","+frm+"->"+key+"->Height);"+endlx;
*/
}
if (int(p&_frm_cmp_prop_check )!=0) lin+=tabl+"ini.key_set(sec,\"CHK_"+key+"\",int("+frm+"->"+key+"->Checked));"+endlx;
if (int(p&_frm_cmp_prop_down )!=0) lin+=tabl+"ini.key_set(sec,\"DWN_"+key+"\",int("+frm+"->"+key+"->Down ));"+endlx;
if (int(p&_frm_cmp_prop_pos )!=0) lin+=tabl+"ini.key_set(sec,\"POS_"+key+"\", "+frm+"->"+key+"->Position);"+endlx;
cpp+=lin;
}
if (end)
{
lin+=tabl+"ini.save(name);"+endlx;
lin+=tabl+"ini.close();"+endlx;
lin+=tabl+"break;"+endlx;
lin+=tabl+"}"+endl;
lin+="//---------------------------------------------------------------------------"+endl;
cpp+=lin;
}
txt+=cpp;
}
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

How to io_control of boost library socket with customized command

I' trying to make an identical function to "ioctl" in c++ style using boost library.
Here is my "c" style code:
int sockfd;
char * id;
struct iwreq wreq;
memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
exit(1);
}
printf("Socket opened successfully \n");
id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;
if (ioctl(sockfd, SIOCGIWESSID, &wreq)) {
fprintf(stderr, "Get ESSID ioctl failed \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description : %s\n",strerror(errno));
exit(2);
}
printf("IOCTL Successfull\n");
printf("ESSID is %s\n", wreq.u.essid.pointer);
I found some relevant example, but I'm not clear how to use it correctly. example
Main function:
boost::asio::ip::udp::socket socket(io_service);
struct iwreq wreq
memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);
id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;
boost::asio::detail::io_control::myCommand command;
command.set(&wreq);
boost::system::error_code ec;
socket.io_control(command, ec);
if (ec)
{
// An error occurred.
}
Custom command:
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/asio/detail/socket_types.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
namespace io_control {
// I/O control command for getting number of bytes available.
class myCommand
{
public:
// Default constructor.
myCommand()
: value_(0)
{
}
// Get the name of the IO control command.
int name() const
{
return static_cast<int>(SIOCGIWESSID);
}
// Set the value of the I/O control command.
void set(struct iwreq* value)
{
value_ = static_cast<detail::ioctl_arg_type>(value);
}
// Get the current value of the I/O control command.
std::size_t get() const
{
return static_cast<struct iwreq*>(value_);
}
// Get the address of the command data.
detail::ioctl_arg_type* data()
{
return &value_;
}
// Get the address of the command data.
const detail::ioctl_arg_type* data() const
{
return &value_;
}
private:
detail::ioctl_arg_type value_;
};
} // namespace io_control
} // namespace detail
} // namespace asio
} // namespace boost
However, the code does not work.
If you have any example code or solution, please let me know.
Thank you.

Calling methods and receiving signals using low-level APIs

I am trying to call the method ReadLocalBdAddrReq and receive its signal ReadLocalBdAddrCfm on dbus using the dbus low level APIs.
I have written the following code with the help of some forum posts and a dbus tutorial.
The thing is, I am not able to receive the signals back. The code is incomplete at some places as I didn't know what should be done.
So please help me so that I can receive the signals for the methods called.
Here the code I have written. Please correct any mistakes I've made.
#include <stdlib.h>
#include <stdio.h>
#include <dbus/dbus.h>
#define OBJ_PATH "/bt/cm"
static dbus_bool_t add_watch(DBusWatch *watch, void *data)
{
if (!dbus_watch_get_enabled(watch))
return TRUE;
int fd = dbus_watch_get_unix_fd(watch);
unsigned int flags = dbus_watch_get_flags(watch);
int f = 0;;
if (flags & DBUS_WATCH_READABLE) {
f |= DBUS_WATCH_READABLE;
printf("Readable\n");
}
if (flags & DBUS_WATCH_WRITABLE) {
printf("Writeable\n");
f |= DBUS_WATCH_WRITABLE;
}
/* this should not be here */
if (dbus_watch_handle(watch, f) == FALSE)
printf("dbus_watch_handle() failed\n");
return TRUE;
}
static void remove_watch(DBusWatch *watch, void *data)
{
printf("In remove watch with fd = [%d]\n",dbus_watch_get_unix_fd(watch));
}
static void toggel_watch(DBusWatch *watch, void *data)
{
printf("In toggel watch\n");
/*
if (dbus_watch_get_enabled(watch))
add_watch(watch, data);
else
remove_watch(watch, data);
*/
}
/* timeout functions */
static dbus_bool_t add_time(DBusTimeout *timeout, void *data)
{
/* Incomplete */
printf("In add_time\n");
if (!dbus_timeout_get_enabled(timeout))
return TRUE;
//dbus_timeout_handle(timeout);
return 0;
}
static void remove_time(DBusTimeout *timeout, void *data)
{
/* Incomplete */
printf("In remove_time\n");
}
static void toggel_time(DBusTimeout *timeout, void *data)
{
/* Incomplete */
printf("In toggel_time\n");
/*
if (dbus_timeout_get_enabled(timeout))
add_timeout(timeout, data);
else
remove_timeout(timeout, data);
*/
}
/* message filter -- handlers to run on all incoming messages*/
static DBusHandlerResult filter (DBusConnection *connection, DBusMessage *message, void *user_data)
{
printf("In filter\n");
char *deviceaddr;
if (dbus_message_is_signal(message, "com.bluegiga.v2.bt.cm", "ReadLocalBdAddrCfm")) {
printf("Signal received is ReadLocalBdAddrCfm\n");
if ((dbus_message_get_args(message,NULL,DBUS_TYPE_STRING, &deviceaddr,DBUS_TYPE_INVALID) == FALSE))
{
printf("Could not get the arguments from the message received\n");
return -2;
}
printf("Got Signal and device address is [%s]\n", deviceaddr);
}
return 0;
}
/* dispatch function-- simply save an indication that messages should be dispatched later, when the main loop is re-entered*/
static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_status, void *data)
{
printf("In dispatch_status\n");
if (new_status == DBUS_DISPATCH_DATA_REMAINS)
{
printf("new dbus dispatch status: DBUS_DISPATCH_DATA_REMAINS [%d]",new_status);
}
}
/* unregister function */
void unregister_func(DBusConnection *connection, void *user_data)
{
}
/* message function - Called when a message is sent to a registered object path. */
static DBusHandlerResult message_func(DBusConnection *connection, DBusMessage *message, void *data)
{
printf("Message [%s] is sent to [%s] from interface [%s] on path [%s] \n",dbus_message_get_member(message),dbus_message_get_destination(message),
dbus_message_get_interface(message),dbus_message_get_path(message)); return 0;
}
DBusObjectPathVTable table = {
.unregister_function = unregister_func,
.message_function = message_func,
};
int main(void) {
DBusMessage* msg;
DBusMessageIter args;
DBusConnection* conn;
DBusError err;
DBusPendingCall* pending;
int ret;
//unsigned int level;
char* appHandle = NULL;
//int *context;
int msg_serial;
int open;
char *deviceaddr;
dbus_error_init(&err);
// connect to the system bus and check for errors
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
exit(1);
}
if (!dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggel_watch, NULL, NULL))
{
printf("Error in dbus_set_watch_functions\n");
dbus_connection_unref(conn);
return -1;
}
/* These functions are responsible for making the application's main loop aware of timeouts */
if (!dbus_connection_set_timeout_functions(conn, add_time, remove_time, toggel_time, NULL, NULL))
{
printf("Error in dbus_set_timeout_functions\n");
dbus_connection_unref(conn);
return -1;
}
/* Used to register the handler functions run on incoming messages*/
if (!dbus_connection_add_filter(conn, filter, NULL, NULL))
{
printf("Error in adding filter\n");
dbus_connection_unref(conn);
return -1;
}
/* Filter added for incoming messages */
/* Set a function to be invoked when the dispatch status changes */
dbus_connection_set_dispatch_status_function(conn, dispatch_status, NULL ,NULL);
/* Register a handler for messages sent to a given path */
if(!dbus_connection_register_object_path(conn, OBJ_PATH, &table, NULL))
{
printf("Error in registering object\n");
return -1;
}
/* sending messages to the outgoing queue */
msg = dbus_message_new_method_call("com.bluegiga.v2.bt.cm", // target for the method call
OBJ_PATH, // object to call on
"com.bluegiga.v2.bt.cm", // interface to call on
"ReadLocalBdAddrReq"); // method name
if (NULL == msg) {
fprintf(stderr, "Message Null\n");
exit(1);
}
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT16,&appHandle)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
fprintf(stderr, "Sending the connections\n");
// send message and get a handle for a reply
if (!dbus_connection_send (conn, msg, &msg_serial)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
fprintf(stderr, "Connection sent and the msg serial is %d\n",msg_serial);
/* Message sent over */
/* not sure whether this should be here or above watch */
while (dbus_connection_get_dispatch_status(conn) == DBUS_DISPATCH_DATA_REMAINS)
{
//printf("Entered in dispatch\n");
/* Processes any incoming data. will call the filters registered by add_filer*/
dbus_connection_dispatch(conn);
}
return 0;
}
After I run this program it has the following output:
Readable
Sending the connections
Connection sent and the msg serial is
2(DBUS_MESSAGE_TYPE_METHOD_RETURN)
If the connection was sent to the object path then message_func should have been called correctly, but it never is called. Have I made any mistake in sending the method call?
You are missing the event loop which is otherwise available by default if you choose to go with one of the bindings. When you get a call to add_watch, libdbus expects that the application will attach an IO handler to it. The IOHandler added by application will watch for an activity on the fd (filedescriptor) queried for the watch. Whenever there is an activity on that file descriptor, the IOHandler will trigger a callback with appropriate flags that you need to convert to DBUS flags before calling dbus_watch_handle.
Suggest that you use glib if you don't know how to use event loops. I am able to get it if I use libUV or libEV as low footprint event loop.

TinyOS periodic Bcast AMSend not received

I want to send messages periodically through this program, the messages are broadcasted fine and I get a sendDone message. The problem is that these messages are not received well. I would really appreciate any help to find out where the problem is?
Here is the code(please ignore unused variables as I have cut a lot of the code):
includes lqer;
module lqer_M{
provides {
interface SplitControl;
interface AMSend[am_id_t id];
interface Receive[uint8_t id];
};
uses {
interface SplitControl as AMControl;
interface Timer<TMilli> as LQERTimer;
interface Random;
interface AMPacket;
interface AMSend as SendPacket;
interface Receive as ReceivePacket;
interface PacketAcknowledgements;
interface Packet;
}
}
implementation{
message_t lqer_msg_;
message_t* p_lqer_msg_;
lqer_table l_table[LQER_FT_SIZE];
node_info info;
uint8_t max=0, Pos=0;
message_t* newADV;
bool busy = FALSE;
command error_t SplitControl.start() {
int i,j;
p_lqer_msg_ = &lqer_msg_;
info.hop=1000;
for(i=0; i<16; i++){
info.m[i]=1;
}
for(i = 0; i< LQER_FT_SIZE; i++) {
l_table[i].nid = INVALID_NODE_ID;
l_table[i].hop = 1000;
for (j=0; j<16; j++)
{
l_table[i].m[j]=1;
}
}
call AMControl.start();
return SUCCESS;
}
command error_t SplitControl.stop() {
call AMControl.stop();
return SUCCESS;
}
event void AMControl.startDone( error_t e ) {
if ( e == SUCCESS ) {
call LQERTimer.startPeriodic( LQER_DEFAULT_PERIOD );
signal SplitControl.startDone(e);
} else {
call AMControl.start();
}
}
event void AMControl.stopDone(error_t e){
call LQERTimer.stop();
signal SplitControl.stopDone(e);
}
event void LQERTimer.fired() {
message_t* lqer_adv_msg;
lqer_adv_hdr* new_ADV=(lqer_adv_hdr*)(lqer_adv_msg->data);
am_addr_t me = call AMPacket.address();
if (me==0001){
new_ADV->src = me;
new_ADV->hop = 0;
newADV= (message_t*)(&new_ADV);
dbg("GRAPE_DBG", "%s\t LQER: Sink address: %d\n", sim_time_string(), me);
call PacketAcknowledgements.requestAck(newADV);
call SendPacket.send( AM_BROADCAST_ADDR, newADV, call Packet.payloadLength(newADV) );
}
}
event message_t* ReceivePacket.receive( message_t* p_msg, void* payload, uint8_t len ) {
lqer_adv_hdr* lqer_hdr = (lqer_adv_hdr*)(p_msg->data);
lqer_adv_hdr* msg_lqer_hdr =(lqer_adv_hdr*)(p_lqer_msg_->data);
uint8_t i;
lqer_adv_hdr* new_ADV =(lqer_adv_hdr*)(p_lqer_msg_->data);
dbg("GRAPE_DBG", "%s\t ADV: RecievedADV dst: \n", sim_time_string());
msg_lqer_hdr->src = lqer_hdr->src;
msg_lqer_hdr->hop = lqer_hdr->hop;
new_ADV->src = msg_lqer_hdr->src;
new_ADV->hop = msg_lqer_hdr->hop;
newADV= (message_t*)(&new_ADV);
call PacketAcknowledgements.requestAck( newADV );
call SendPacket.send( AM_BROADCAST_ADDR, newADV, call Packet.payloadLength(newADV) );
return p_msg;
}
command error_t AMSend.cancel[am_id_t id](message_t* msg) {
return call SendPacket.cancel(msg);
}
command uint8_t AMSend.maxPayloadLength[am_id_t id]() {
return call Packet.maxPayloadLength();
}
command void* AMSend.getPayload[am_id_t id](message_t* m, uint8_t len) {
return call Packet.getPayload(m, 0);
}
default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t err) {
return;
}
default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
return msg;
}
command error_t AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len)
{
call SendPacket.send( TOS_BCAST_ADDR , msg, call Packet.payloadLength(msg) );
return SUCCESS;
}
event void SendPacket.sendDone(message_t* p_msg, error_t e) {
dbg("GRAPE_DBG", "%s\t ADV: SendDone\n", sim_time_string());
if( p_msg== newADV)
busy=FALSE;
}
}
You should look at what is the error value in the sendDone event. It is possible that send returns success, but the sending fail after that, and the error code is returned in the sendDone. These error includes ENOACK, ENOMEM, etc.
Also, check your destination address and the AM address of the receiver.