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#include <linux/string.h>
34#include <linux/socket.h>
35#include <linux/seq_file.h>
36
37#include <net/irda/irda.h>
38#include <net/irda/irlmp.h>
39
40#include <net/irda/discovery.h>
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
58{
59 discovery_t *discovery, *node;
60 unsigned long flags;
61
62
63 new->firststamp = new->timestamp;
64
65 spin_lock_irqsave(&cachelog->hb_spinlock, flags);
66
67
68
69
70
71
72
73 discovery = (discovery_t *) hashbin_get_first(cachelog);
74 while (discovery != NULL ) {
75 node = discovery;
76
77
78 discovery = (discovery_t *) hashbin_get_next(cachelog);
79
80 if ((node->data.saddr == new->data.saddr) &&
81 ((node->data.daddr == new->data.daddr) ||
82 (strcmp(node->data.info, new->data.info) == 0)))
83 {
84
85
86
87 hashbin_remove_this(cachelog, (irda_queue_t *) node);
88
89 if(u16ho(node->data.hints) == u16ho(new->data.hints))
90
91 new->firststamp = node->firststamp;
92 kfree(node);
93 }
94 }
95
96
97 hashbin_insert(cachelog, (irda_queue_t *) new, new->data.daddr, NULL);
98
99 spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
100}
101
102
103
104
105
106
107
108void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log)
109{
110 discovery_t *discovery;
111
112 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
113
114
115
116
117
118
119
120 if (log == NULL) {
121
122 return;
123 }
124
125
126
127
128
129
130 discovery = (discovery_t *) hashbin_remove_first(log);
131 while (discovery != NULL) {
132 irlmp_add_discovery(cachelog, discovery);
133
134 discovery = (discovery_t *) hashbin_remove_first(log);
135 }
136
137
138 hashbin_delete(log, (FREE_FUNC) kfree);
139}
140
141
142
143
144
145
146
147
148
149void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
150{
151 discovery_t * discovery;
152 discovery_t * curr;
153 unsigned long flags;
154 discinfo_t * buffer = NULL;
155 int n;
156 int i = 0;
157
158 IRDA_ASSERT(log != NULL, return;);
159 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
160
161 spin_lock_irqsave(&log->hb_spinlock, flags);
162
163 discovery = (discovery_t *) hashbin_get_first(log);
164 while (discovery != NULL) {
165
166 curr = discovery;
167 discovery = (discovery_t *) hashbin_get_next(log);
168
169
170 if ((curr->data.saddr == saddr) &&
171 (force ||
172 ((jiffies - curr->timestamp) > DISCOVERY_EXPIRE_TIMEOUT)))
173 {
174
175
176
177
178
179 if(buffer == NULL) {
180
181 n = HASHBIN_GET_SIZE(log);
182 buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC);
183 if (buffer == NULL) {
184 spin_unlock_irqrestore(&log->hb_spinlock, flags);
185 return;
186 }
187
188 }
189
190
191 memcpy(&(buffer[i]), &(curr->data),
192 sizeof(discinfo_t));
193 i++;
194
195
196 curr = hashbin_remove_this(log, (irda_queue_t *) curr);
197 kfree(curr);
198 }
199 }
200
201
202
203
204
205 spin_unlock_irqrestore(&log->hb_spinlock, flags);
206
207 if(buffer == NULL)
208 return;
209
210
211 irlmp_discovery_expiry(buffer, i);
212
213
214 kfree(buffer);
215}
216
217#if 0
218
219
220
221
222
223
224void irlmp_dump_discoveries(hashbin_t *log)
225{
226 discovery_t *discovery;
227
228 IRDA_ASSERT(log != NULL, return;);
229
230 discovery = (discovery_t *) hashbin_get_first(log);
231 while (discovery != NULL) {
232 IRDA_DEBUG(0, "Discovery:\n");
233 IRDA_DEBUG(0, " daddr=%08x\n", discovery->data.daddr);
234 IRDA_DEBUG(0, " saddr=%08x\n", discovery->data.saddr);
235 IRDA_DEBUG(0, " nickname=%s\n", discovery->data.info);
236
237 discovery = (discovery_t *) hashbin_get_next(log);
238 }
239}
240#endif
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
263 __u16 mask, int old_entries)
264{
265 discovery_t * discovery;
266 unsigned long flags;
267 discinfo_t * buffer = NULL;
268 int j_timeout = (sysctl_discovery_timeout * HZ);
269 int n;
270 int i = 0;
271
272 IRDA_ASSERT(pn != NULL, return NULL;);
273 IRDA_ASSERT(log != NULL, return NULL;);
274
275
276 spin_lock_irqsave(&log->hb_spinlock, flags);
277
278 discovery = (discovery_t *) hashbin_get_first(log);
279 while (discovery != NULL) {
280
281
282
283 if ((u16ho(discovery->data.hints) & mask) &&
284 ((old_entries) ||
285 ((jiffies - discovery->firststamp) < j_timeout)) ) {
286
287
288
289
290
291 if(buffer == NULL) {
292
293 n = HASHBIN_GET_SIZE(log);
294 buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC);
295 if (buffer == NULL) {
296 spin_unlock_irqrestore(&log->hb_spinlock, flags);
297 return NULL;
298 }
299
300 }
301
302
303 memcpy(&(buffer[i]), &(discovery->data),
304 sizeof(discinfo_t));
305 i++;
306 }
307 discovery = (discovery_t *) hashbin_get_next(log);
308 }
309
310 spin_unlock_irqrestore(&log->hb_spinlock, flags);
311
312
313 *pn = i;
314 return(buffer);
315}
316
317#ifdef CONFIG_PROC_FS
318static inline discovery_t *discovery_seq_idx(loff_t pos)
319
320{
321 discovery_t *discovery;
322
323 for (discovery = (discovery_t *) hashbin_get_first(irlmp->cachelog);
324 discovery != NULL;
325 discovery = (discovery_t *) hashbin_get_next(irlmp->cachelog)) {
326 if (pos-- == 0)
327 break;
328 }
329
330 return discovery;
331}
332
333static void *discovery_seq_start(struct seq_file *seq, loff_t *pos)
334{
335 spin_lock_irq(&irlmp->cachelog->hb_spinlock);
336 return *pos ? discovery_seq_idx(*pos - 1) : SEQ_START_TOKEN;
337}
338
339static void *discovery_seq_next(struct seq_file *seq, void *v, loff_t *pos)
340{
341 ++*pos;
342 return (v == SEQ_START_TOKEN)
343 ? (void *) hashbin_get_first(irlmp->cachelog)
344 : (void *) hashbin_get_next(irlmp->cachelog);
345}
346
347static void discovery_seq_stop(struct seq_file *seq, void *v)
348{
349 spin_unlock_irq(&irlmp->cachelog->hb_spinlock);
350}
351
352static int discovery_seq_show(struct seq_file *seq, void *v)
353{
354 if (v == SEQ_START_TOKEN)
355 seq_puts(seq, "IrLMP: Discovery log:\n\n");
356 else {
357 const discovery_t *discovery = v;
358
359 seq_printf(seq, "nickname: %s, hint: 0x%02x%02x",
360 discovery->data.info,
361 discovery->data.hints[0],
362 discovery->data.hints[1]);
363#if 0
364 if ( discovery->data.hints[0] & HINT_PNP)
365 seq_puts(seq, "PnP Compatible ");
366 if ( discovery->data.hints[0] & HINT_PDA)
367 seq_puts(seq, "PDA/Palmtop ");
368 if ( discovery->data.hints[0] & HINT_COMPUTER)
369 seq_puts(seq, "Computer ");
370 if ( discovery->data.hints[0] & HINT_PRINTER)
371 seq_puts(seq, "Printer ");
372 if ( discovery->data.hints[0] & HINT_MODEM)
373 seq_puts(seq, "Modem ");
374 if ( discovery->data.hints[0] & HINT_FAX)
375 seq_puts(seq, "Fax ");
376 if ( discovery->data.hints[0] & HINT_LAN)
377 seq_puts(seq, "LAN Access ");
378
379 if ( discovery->data.hints[1] & HINT_TELEPHONY)
380 seq_puts(seq, "Telephony ");
381 if ( discovery->data.hints[1] & HINT_FILE_SERVER)
382 seq_puts(seq, "File Server ");
383 if ( discovery->data.hints[1] & HINT_COMM)
384 seq_puts(seq, "IrCOMM ");
385 if ( discovery->data.hints[1] & HINT_OBEX)
386 seq_puts(seq, "IrOBEX ");
387#endif
388 seq_printf(seq,", saddr: 0x%08x, daddr: 0x%08x\n\n",
389 discovery->data.saddr,
390 discovery->data.daddr);
391
392 seq_putc(seq, '\n');
393 }
394 return 0;
395}
396
397static struct seq_operations discovery_seq_ops = {
398 .start = discovery_seq_start,
399 .next = discovery_seq_next,
400 .stop = discovery_seq_stop,
401 .show = discovery_seq_show,
402};
403
404static int discovery_seq_open(struct inode *inode, struct file *file)
405{
406 IRDA_ASSERT(irlmp != NULL, return -EINVAL;);
407
408 return seq_open(file, &discovery_seq_ops);
409}
410
411struct file_operations discovery_seq_fops = {
412 .owner = THIS_MODULE,
413 .open = discovery_seq_open,
414 .read = seq_read,
415 .llseek = seq_lseek,
416 .release = seq_release,
417};
418#endif
419