OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [tei.c] - Blame information for rev 1772

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: tei.c,v 1.1 2005-12-20 10:17:01 jcastillo Exp $
2
 
3
 * Author       Karsten Keil (keil@isdn4linux.de)
4
 *              based on the teles driver from Jan den Ouden
5
 *
6
 *              This file is (c) under GNU PUBLIC LICENSE
7
 *              For changes and modifications please read
8
 *              ../../../Documentation/isdn/HiSax.cert
9
 *
10
 * Thanks to    Jan den Ouden
11
 *              Fritz Elfert
12
 *
13
 * $Log: not supported by cvs2svn $
14
 * Revision 1.1.1.1  2001/09/10 07:44:19  simons
15
 * Initial import
16
 *
17
 * Revision 1.1.1.1  2001/07/02 17:58:32  simons
18
 * Initial revision
19
 *
20
 * Revision 1.8.2.7  1998/11/03 00:07:35  keil
21
 * certification related changes
22
 * fixed logging for smaller stack use
23
 *
24
 * Revision 1.8.2.6  1998/05/27 18:06:21  keil
25
 * HiSax 3.0
26
 *
27
 * Revision 1.8.2.5  1998/03/07 23:15:38  tsbogend
28
 * made HiSax working on Linux/Alpha
29
 *
30
 * Revision 1.8.2.4  1998/01/27 22:43:49  keil
31
 * fixed MDL_ASSIGN_REQ
32
 *
33
 * Revision 1.8.2.3  1997/11/15 18:54:20  keil
34
 * cosmetics
35
 *
36
 * Revision 1.8.2.2  1997/10/17 22:14:23  keil
37
 * update to last hisax version
38
 *
39
 * Revision 2.2  1997/07/31 19:24:39  keil
40
 * fixed a warning
41
 *
42
 * Revision 2.1  1997/07/31 11:50:16  keil
43
 * ONE TEI and FIXED TEI handling
44
 *
45
 * Revision 2.0  1997/07/27 21:13:30  keil
46
 * New TEI managment
47
 *
48
 * Revision 1.9  1997/06/26 11:18:02  keil
49
 * New managment
50
 *
51
 * Revision 1.8  1997/04/07 22:59:08  keil
52
 * GFP_KERNEL --> GFP_ATOMIC
53
 *
54
 * Revision 1.7  1997/04/06 22:54:03  keil
55
 * Using SKB's
56
 *
57
 * Old log removed/ KKe
58
 *
59
 */
60
#define __NO_VERSION__
61
#include "hisax.h"
62
#include "isdnl2.h"
63
#include <linux/random.h>
64
 
65
const char *tei_revision = "$Revision: 1.1 $";
66
 
67
#define ID_REQUEST      1
68
#define ID_ASSIGNED     2
69
#define ID_DENIED       3
70
#define ID_CHK_REQ      4
71
#define ID_CHK_RES      5
72
#define ID_REMOVE       6
73
#define ID_VERIFY       7
74
 
75
#define TEI_ENTITY_ID   0xf
76
 
77
static
78
struct Fsm teifsm =
79
{NULL, 0, 0, NULL, NULL};
80
 
81
void tei_handler(struct PStack *st, u_char pr, struct sk_buff *skb);
82
 
83
enum {
84
        ST_TEI_NOP,
85
        ST_TEI_IDREQ,
86
        ST_TEI_IDVERIFY,
87
};
88
 
89
#define TEI_STATE_COUNT (ST_TEI_IDVERIFY+1)
90
 
91
static char *strTeiState[] =
92
{
93
        "ST_TEI_NOP",
94
        "ST_TEI_IDREQ",
95
        "ST_TEI_IDVERIFY",
96
};
97
 
98
enum {
99
        EV_IDREQ,
100
        EV_ASSIGN,
101
        EV_DENIED,
102
        EV_CHKREQ,
103
        EV_REMOVE,
104
        EV_VERIFY,
105
        EV_T202,
106
};
107
 
108
#define TEI_EVENT_COUNT (EV_T202+1)
109
 
110
static char *strTeiEvent[] =
111
{
112
        "EV_IDREQ",
113
        "EV_ASSIGN",
114
        "EV_DENIED",
115
        "EV_CHKREQ",
116
        "EV_REMOVE",
117
        "EV_VERIFY",
118
        "EV_T202",
119
};
120
 
121
unsigned int
122
random_ri(void)
123
{
124
        unsigned int x;
125
 
126
        get_random_bytes(&x, sizeof(x));
127
        return (x & 0xffff);
128
}
129
 
130
static struct PStack *
131
findtei(struct PStack *st, int tei)
132
{
133
        struct PStack *ptr = *(st->l1.stlistp);
134
 
135
        if (tei == 127)
136
                return (NULL);
137
 
138
        while (ptr)
139
                if (ptr->l2.tei == tei)
140
                        return (ptr);
141
                else
142
                        ptr = ptr->next;
143
        return (NULL);
144
}
145
 
146
static void
147
put_tei_msg(struct PStack *st, u_char m_id, unsigned int ri, u_char tei)
148
{
149
        struct sk_buff *skb;
150
        u_char *bp;
151
 
152
        if (!(skb = alloc_skb(8, GFP_ATOMIC))) {
153
                printk(KERN_WARNING "HiSax: No skb for TEI manager\n");
154
                return;
155
        }
156
        SET_SKB_FREE(skb);
157
        bp = skb_put(skb, 3);
158
        bp[0] = (TEI_SAPI << 2);
159
        bp[1] = (GROUP_TEI << 1) | 0x1;
160
        bp[2] = UI;
161
        bp = skb_put(skb, 5);
162
        bp[0] = TEI_ENTITY_ID;
163
        bp[1] = ri >> 8;
164
        bp[2] = ri & 0xff;
165
        bp[3] = m_id;
166
        bp[4] = (tei << 1) | 1;
167
        st->l2.l2l1(st, PH_DATA | REQUEST, skb);
168
}
169
 
170
static void
171
tei_id_request(struct FsmInst *fi, int event, void *arg)
172
{
173
        struct PStack *st = fi->userdata;
174
 
175
        if (st->l2.tei != -1) {
176
                st->ma.tei_m.printdebug(&st->ma.tei_m,
177
                        "assign request for allready asigned tei %d",
178
                        st->l2.tei);
179
                return;
180
        }
181
        st->ma.ri = random_ri();
182
        if (st->ma.debug)
183
                st->ma.tei_m.printdebug(&st->ma.tei_m,
184
                        "assign request ri %d", st->ma.ri);
185
        put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
186
        FsmChangeState(&st->ma.tei_m, ST_TEI_IDREQ);
187
        FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 1);
188
        st->ma.N202 = 3;
189
}
190
 
191
static void
192
tei_id_assign(struct FsmInst *fi, int event, void *arg)
193
{
194
        struct PStack *ost, *st = fi->userdata;
195
        struct sk_buff *skb = arg;
196
        struct IsdnCardState *cs;
197
        int ri, tei;
198
 
199
        ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
200
        tei = skb->data[4] >> 1;
201
        if (st->ma.debug)
202
                st->ma.tei_m.printdebug(&st->ma.tei_m,
203
                        "identity assign ri %d tei %d", ri, tei);
204
        if ((ost = findtei(st, tei))) {         /* same tei is in use */
205
                if (ri != ost->ma.ri) {
206
                        st->ma.tei_m.printdebug(&st->ma.tei_m,
207
                                "possible duplicate assignment tei %d", tei);
208
                        ost->l2.l2tei(ost, MDL_ERROR | RESPONSE, NULL);
209
                }
210
        } else if (ri == st->ma.ri) {
211
                FsmDelTimer(&st->ma.t202, 1);
212
                FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
213
                st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) tei);
214
                cs = (struct IsdnCardState *) st->l1.hardware;
215
                cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
216
        }
217
}
218
 
219
static void
220
tei_id_denied(struct FsmInst *fi, int event, void *arg)
221
{
222
        struct PStack *st = fi->userdata;
223
        struct sk_buff *skb = arg;
224
        int ri, tei;
225
 
226
        ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
227
        tei = skb->data[4] >> 1;
228
        if (st->ma.debug)
229
                st->ma.tei_m.printdebug(&st->ma.tei_m,
230
                        "identity denied ri %d tei %d", ri, tei);
231
}
232
 
233
static void
234
tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
235
{
236
        struct PStack *st = fi->userdata;
237
        struct sk_buff *skb = arg;
238
        int tei;
239
 
240
        tei = skb->data[4] >> 1;
241
        if (st->ma.debug)
242
                st->ma.tei_m.printdebug(&st->ma.tei_m,
243
                        "identity check req tei %d", tei);
244
        if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
245
                FsmDelTimer(&st->ma.t202, 4);
246
                FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
247
                put_tei_msg(st, ID_CHK_RES, random_ri(), st->l2.tei);
248
        }
249
}
250
 
251
static void
252
tei_id_remove(struct FsmInst *fi, int event, void *arg)
253
{
254
        struct PStack *st = fi->userdata;
255
        struct sk_buff *skb = arg;
256
        struct IsdnCardState *cs;
257
        int tei;
258
 
259
        tei = skb->data[4] >> 1;
260
        if (st->ma.debug)
261
                st->ma.tei_m.printdebug(&st->ma.tei_m,
262
                        "identity remove tei %d", tei);
263
        if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
264
                FsmDelTimer(&st->ma.t202, 5);
265
                FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
266
                st->l3.l3l2(st, MDL_REMOVE | REQUEST, 0);
267
                cs = (struct IsdnCardState *) st->l1.hardware;
268
                cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
269
        }
270
}
271
 
272
static void
273
tei_id_verify(struct FsmInst *fi, int event, void *arg)
274
{
275
        struct PStack *st = fi->userdata;
276
 
277
        if (st->ma.debug)
278
                st->ma.tei_m.printdebug(&st->ma.tei_m,
279
                        "id verify request for tei %d", st->l2.tei);
280
        put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
281
        FsmChangeState(&st->ma.tei_m, ST_TEI_IDVERIFY);
282
        FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 2);
283
        st->ma.N202 = 2;
284
}
285
 
286
static void
287
tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
288
{
289
        struct PStack *st = fi->userdata;
290
        struct IsdnCardState *cs;
291
 
292
        if (--st->ma.N202) {
293
                st->ma.ri = random_ri();
294
                if (st->ma.debug)
295
                        st->ma.tei_m.printdebug(&st->ma.tei_m,
296
                                "assign req(%d) ri %d", 4 - st->ma.N202,
297
                                st->ma.ri);
298
                put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
299
                FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 3);
300
        } else {
301
                st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req failed");
302
                st->l3.l3l2(st, MDL_ERROR | RESPONSE, 0);
303
                cs = (struct IsdnCardState *) st->l1.hardware;
304
                cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
305
                FsmChangeState(fi, ST_TEI_NOP);
306
        }
307
}
308
 
309
static void
310
tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
311
{
312
        struct PStack *st = fi->userdata;
313
        struct IsdnCardState *cs;
314
 
315
        if (--st->ma.N202) {
316
                if (st->ma.debug)
317
                        st->ma.tei_m.printdebug(&st->ma.tei_m,
318
                                "id verify req(%d) for tei %d",
319
                                3 - st->ma.N202, st->l2.tei);
320
                put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
321
                FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 4);
322
        } else {
323
                st->ma.tei_m.printdebug(&st->ma.tei_m,
324
                        "verify req for tei %d failed", st->l2.tei);
325
                st->l3.l3l2(st, MDL_REMOVE | REQUEST, 0);
326
                cs = (struct IsdnCardState *) st->l1.hardware;
327
                cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
328
                FsmChangeState(fi, ST_TEI_NOP);
329
        }
330
}
331
 
332
static void
333
tei_l1l2(struct PStack *st, int pr, void *arg)
334
{
335
        struct sk_buff *skb = arg;
336
        int mt;
337
 
338
        if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
339
                dev_kfree_skb(skb, FREE_READ);
340
                return;
341
        }
342
 
343
        if (pr == (PH_DATA | INDICATION)) {
344
                if (skb->len < 3) {
345
                        st->ma.tei_m.printdebug(&st->ma.tei_m,
346
                                "short mgr frame %ld/3", skb->len);
347
                } else if (((skb->data[0] >> 2) != TEI_SAPI) ||
348
                           ((skb->data[1] >> 1) != GROUP_TEI)) {
349
                        st->ma.tei_m.printdebug(&st->ma.tei_m,
350
                                "wrong mgr sapi/tei %x/%x",
351
                                skb->data[0], skb->data[1]);
352
                } else if ((skb->data[2] & 0xef) != UI) {
353
                        st->ma.tei_m.printdebug(&st->ma.tei_m,
354
                                "mgr frame is not ui %x", skb->data[2]);
355
                } else {
356
                        skb_pull(skb, 3);
357
                        if (skb->len < 5) {
358
                                st->ma.tei_m.printdebug(&st->ma.tei_m,
359
                                        "short mgr frame %ld/5", skb->len);
360
                        } else if (skb->data[0] != TEI_ENTITY_ID) {
361
                                /* wrong management entity identifier, ignore */
362
                                st->ma.tei_m.printdebug(&st->ma.tei_m,
363
                                        "tei handler wrong entity id %x",
364
                                        skb->data[0]);
365
                        } else {
366
                                mt = skb->data[3];
367
                                if (mt == ID_ASSIGNED)
368
                                        FsmEvent(&st->ma.tei_m, EV_ASSIGN, skb);
369
                                else if (mt == ID_DENIED)
370
                                        FsmEvent(&st->ma.tei_m, EV_DENIED, skb);
371
                                else if (mt == ID_CHK_REQ)
372
                                        FsmEvent(&st->ma.tei_m, EV_CHKREQ, skb);
373
                                else if (mt == ID_REMOVE)
374
                                        FsmEvent(&st->ma.tei_m, EV_REMOVE, skb);
375
                                else {
376
                                        st->ma.tei_m.printdebug(&st->ma.tei_m,
377
                                                "tei handler wrong mt %x\n", mt);
378
                                }
379
                        }
380
                }
381
        } else {
382
                st->ma.tei_m.printdebug(&st->ma.tei_m,
383
                        "tei handler wrong pr %x\n", pr);
384
        }
385
        dev_kfree_skb(skb, FREE_READ);
386
}
387
 
388
static void
389
tei_l2tei(struct PStack *st, int pr, void *arg)
390
{
391
        struct IsdnCardState *cs;
392
 
393
        if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
394
                if (pr == (MDL_ASSIGN | INDICATION)) {
395
                        if (st->ma.debug)
396
                                st->ma.tei_m.printdebug(&st->ma.tei_m,
397
                                        "fixed assign tei %d", st->l2.tei);
398
                        st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei);
399
                        cs = (struct IsdnCardState *) st->l1.hardware;
400
                        cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
401
                }
402
                return;
403
        }
404
        switch (pr) {
405
                case (MDL_ASSIGN | INDICATION):
406
                        FsmEvent(&st->ma.tei_m, EV_IDREQ, arg);
407
                        break;
408
                case (MDL_ERROR | REQUEST):
409
                        FsmEvent(&st->ma.tei_m, EV_VERIFY, arg);
410
                        break;
411
                default:
412
                        break;
413
        }
414
}
415
 
416
static void
417
tei_debug(struct FsmInst *fi, char *fmt, ...)
418
{
419
        va_list args;
420
        struct PStack *st = fi->userdata;
421
 
422
        va_start(args, fmt);
423
        VHiSax_putstatus(st->l1.hardware, "tei ", fmt, args);
424
        va_end(args);
425
}
426
 
427
void
428
setstack_tei(struct PStack *st)
429
{
430
        st->l2.l2tei = tei_l2tei;
431
        st->ma.T202 = 2000;     /* T202  2000 milliseconds */
432
        st->l1.l1tei = tei_l1l2;
433
        st->ma.debug = 1;
434
        st->ma.tei_m.fsm = &teifsm;
435
        st->ma.tei_m.state = ST_TEI_NOP;
436
        st->ma.tei_m.debug = 1;
437
        st->ma.tei_m.userdata = st;
438
        st->ma.tei_m.userint = 0;
439
        st->ma.tei_m.printdebug = tei_debug;
440
        FsmInitTimer(&st->ma.tei_m, &st->ma.t202);
441
}
442
 
443
void
444
init_tei(struct IsdnCardState *cs, int protocol)
445
{
446
}
447
 
448
void
449
release_tei(struct IsdnCardState *cs)
450
{
451
        struct PStack *st = cs->stlist;
452
 
453
        while (st) {
454
                FsmDelTimer(&st->ma.t202, 1);
455
                st = st->next;
456
        }
457
}
458
 
459
static struct FsmNode TeiFnList[] HISAX_INITDATA =
460
{
461
        {ST_TEI_NOP, EV_IDREQ, tei_id_request},
462
        {ST_TEI_NOP, EV_VERIFY, tei_id_verify},
463
        {ST_TEI_NOP, EV_REMOVE, tei_id_remove},
464
        {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req},
465
        {ST_TEI_IDREQ, EV_T202, tei_id_req_tout},
466
        {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
467
        {ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
468
        {ST_TEI_IDVERIFY, EV_T202, tei_id_ver_tout},
469
        {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
470
        {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
471
};
472
 
473
#define TEI_FN_COUNT (sizeof(TeiFnList)/sizeof(struct FsmNode))
474
 
475
HISAX_INITFUNC(void
476
TeiNew(void))
477
{
478
        teifsm.state_count = TEI_STATE_COUNT;
479
        teifsm.event_count = TEI_EVENT_COUNT;
480
        teifsm.strEvent = strTeiEvent;
481
        teifsm.strState = strTeiState;
482
        FsmNew(&teifsm, TeiFnList, TEI_FN_COUNT);
483
}
484
 
485
void
486
TeiFree(void)
487
{
488
        FsmFree(&teifsm);
489
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.