#include "Scheduler.h" #include "TimeOut.h" #include "BusAccess.h" #include "IrdaAddress.h" #include "ObexStream.h" #include "ivl/Reaction.h" #include #include #include class IvlEvent; /* Global variables. This is because we use IvlCallbacks and functions instead of IvlReactions and objects. But this is only a test... */ IvlBusAccess* A; IvlCallback* C; IvlObexStream* I; IvlDictionnaryOf Peers (16); IvlListOf Pending; int NbPending = 0; int PrevNbPending = -1; /* This is an example of how to emit messages on the bus. Here, this function is called periodically so as to demonstrate the behaviour of the bus. */ void foo (Millisecond t) { /* find accessible devices */ IvlListOf la; if (IvlIrdaAddress::DiscoverPeers (I->GetFd (), la) == 0) { /* if none available, delete all peers */ IvlObexAgent* ag; bool found = false; while (ag = Peers.RemoveOne ()) { ag.Trash (); found = true; } if (found) cerr << "no more devices available\n"; if (found || NbPending != PrevNbPending) cerr << NbPending << " pending message" << (NbPending == 1 ? "\n" : "s\n"); PrevNbPending = NbPending; return; } PrevNbPending = NbPending; IvlDictionnaryOf copy = Peers; /* add new addresses to Peers and create corresponding agents */ IvlListIterOf li = la; while (++li) { char buf[1024]; (*li)->StrRepr (buf); if (copy.Remove (buf) == 0) { Peers[buf] = new IvlObexAgent (*li, I); cerr << "located " << buf << "\n"; } } /* remove obsolete addresses from Peers and delete corresponding agents */ IvlHashCellIterOf hi = *(IvlHashTableOf*)© while (++hi) { IvlHashCellOf* c = *hi; cerr << "deleting obsolete " << (const char*) c->GetKey () << "\n"; Peers.Remove (c->GetKey ()); IvlObexAgent* ag = c->GetInfo (); delete ag; } /* send objects to peers */ IvlObexObject* p; while (p = Pending.RemoveFirst ()) { --NbPending; cerr << "sending object\n"; IvlHashIterOf hj = *(IvlHashTableOf*)&Peers; while (++hj) (*hj)->SendObject (*p); delete p; } } void obex_send (IvlEvent& ev) { IvlBusEvent* be = dynamic_cast (&ev); if (!be) return; if (be->NbMatches < 3) { cerr << "incomplete OBEX Ivy message\n"; return; } IvlListIterOf li = be->MatchList; IvlObexObject* o = new IvlObexObject; o->SetClass (atoi (**++li)); o->SetName (**++li); o->SetBody (**++li); Pending.Append (o); ++NbPending; } void irda_agent_ready (IvlEvent& ev) { IvlObexAgentEvent* ae = dynamic_cast (&ev); if (!ae) return; IvlObexAgent* a = ae->GetAgent (); A->Emit ("new IRDA Agent"); // C->SubscribeTo (a->Bye); } #define MEMO_PAD_ID 0x6d656d6f /* "memo" *.txt */ main (int argc, const char** argv) { /* initialize communication library */ IvlOpen (); /* create bus access */ IvlBusAccess a ("Ivl test"); A = &a; /*** IRDA test ***/ /* periodically send messages on the bus (see foo for timeout handling) */ IvlTimeOut t (1000, foo); if (argc > 2) t.Stop (); /* create IRDA OBEX access */ IvlObexStream irl (new IvlIrdaAddress); I = &irl; if (argc <= 1) { IvlObexObject* o = new IvlObexObject; o->SetClass (MEMO_PAD_ID); o->SetName ("Essai1"); o->SetBody ("Ceci est un mémo\nenvoyé depuis Linux vers\nle Palm\n"); Pending.Append (o); ++NbPending; } /* test connection to first available device */ IvlCallback c2 (obex_send); a.Subscribe (c2, "^OBEX class=(.*) name=(.*) body=(.*)"); IvlCallback c5 (irda_agent_ready); c5.SubscribeTo (irl.NewAgents); IvlLoop (); }