summaryrefslogtreecommitdiff
path: root/comm/testirda.cc
blob: 100c268d44e517f1690c7cef05bc82d7c4c6069e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "Scheduler.h"
#include "TimeOut.h"
#include "BusAccess.h"
#include "IrdaAddress.h"
#include "ObexStream.h"
#include "ivl/Reaction.h"
#include <stdlib.h>
#include <stdio.h>
#include <ostream.h>
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<IvlObexAgent> Peers (16);
IvlListOf<IvlObexObject> 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<IvlIrdaAddress> 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<IvlObexAgent> copy = Peers;

	/* add new addresses to Peers and create corresponding agents */
	IvlListIterOf<IvlIrdaAddress> 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<IvlObexAgent> hi = *(IvlHashTableOf<IvlObexAgent>*)&copy;
	while (++hi) {
		IvlHashCellOf<IvlObexAgent>* 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<IvlObexAgent> hj = *(IvlHashTableOf<IvlObexAgent>*)&Peers;
		while (++hj)
			(*hj)->SendObject (*p);
		delete p;
	}

	
}

void
obex_send (IvlEvent& ev)
{
	IvlBusEvent* be = dynamic_cast<IvlBusEvent*> (&ev);
	if (!be)
		return;
	if (be->NbMatches < 3) {
		cerr << "incomplete OBEX Ivy message\n";
		return;
	}

	IvlListIterOf<IvlString> 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<IvlObexAgentEvent*> (&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 ();
}