This source file includes following definitions.
- stat_debug
- stat_error
- my_atoi
- r1
- ll_hangup
- r2
- r2_1
- r2_2
- r3
- r3_1
- r4
- r5
- r6
- r7
- r8
- r9
- r10
- r12
- prp
- r15
- r16
- r17
- r17_1
- r18
- r19
- r20
- r21
- r22
- r23
- r23_1
- r24
- r25
- r26
- lc_r1
- lc_r6
- lc_r2
- lc_r3
- lc_r4
- lc_r5
- CallcNew
- CallcFree
- release_ds
- cc_l1man
- cc_l2man
- dcc_l1man
- dcc_l2man
- ll_handler
- init_is
- callc_debug
- lc_debug
- dlc_debug
- lccall_d
- lccall_b
- init_chan
- CallcNewChan
- release_is
- release_chan
- CallcFreeChan
- lldata_handler
- lltrans_handler
- ll_writewakeup
- init_ds
- channel_report
- command_debug
- distr_debug
- teles_command
- teles_writebuf
- strcpyupto
1
2
3
4
5
6
7
8
9
10
11
12 #define __NO_VERSION__
13 #include "teles.h"
14
15 extern struct IsdnCard cards[];
16 extern int nrcards;
17 extern int drid;
18 extern isdn_if iif;
19 extern void teles_mod_dec_use_count(void);
20 extern void teles_mod_inc_use_count(void);
21
22 static int init_ds(int chan, int incoming);
23 static void release_ds(int chan);
24 static char *strcpyupto(char *dest, char *src, char upto);
25
26 static struct Fsm callcfsm =
27 {NULL, 0, 0}, lcfsm =
28 {NULL, 0, 0};
29
30 struct Channel *chanlist;
31 static int chancount = 0;
32 unsigned int debugflags = 0;
33
34 #define TMR_DCHAN_EST 2000
35
36 static void
37 stat_debug(struct Channel *chanp, char *s)
38 {
39 char tmp[100], tm[32];
40
41 jiftime(tm, jiffies);
42 sprintf(tmp, "%s Channel %d HL->LL %s\n", tm, chanp->chan, s);
43 teles_putstatus(tmp);
44 }
45
46 #ifdef DEFINED_BUT_NOT_USED
47 static void
48 stat_error(struct Channel *chanp, char *s)
49 {
50 char tmp[100];
51
52 sprintf(tmp, "Channel %d: %s\n", chanp->chan, s);
53 teles_putstatus(tmp);
54 }
55 #endif
56
57 enum {
58 ST_NULL,
59 ST_OUT,
60 ST_CLEAR,
61 ST_OUT_W,
62 ST_REL_W,
63 ST_IN_W,
64 ST_IN,
65 ST_IN_SETUP,
66 ST_IN_DACT,
67 ST_OUT_ESTB,
68 ST_ACTIVE,
69 ST_BC_HANGUP,
70 ST_PRO_W,
71 ST_ANT_W,
72 ST_DISC_BC_HANGUP,
73 ST_OUT_W_HANGUP,
74 ST_D_ERR,
75 };
76
77 #define STATE_COUNT (ST_D_ERR+1)
78
79 static char *strState[] =
80 {
81 "ST_NULL",
82 "ST_OUT",
83 "ST_CLEAR",
84 "ST_OUT_W",
85 "ST_REL_W",
86 "ST_IN_W",
87 "ST_IN",
88 "ST_IN_SETUP",
89 "ST_IN_DACT",
90 "ST_OUT_ESTB",
91 "ST_ACTIVE",
92 "ST_BC_HANGUP",
93 "ST_PRO_W",
94 "ST_ANT_W",
95 "ST_DISC_BC_HANGUP",
96 "ST_OUT_W_HANGUP",
97 "ST_D_ERR",
98 };
99
100 enum {
101 EV_DIAL,
102 EV_SETUP_CNF,
103 EV_ACCEPTB,
104 EV_DISCONNECT_CNF,
105 EV_DISCONNECT_IND,
106 EV_RELEASE_CNF,
107 EV_DLEST,
108 EV_DLRL,
109 EV_SETUP_IND,
110 EV_RELEASE_IND,
111 EV_ACCEPTD,
112 EV_SETUP_CMPL_IND,
113 EV_BC_EST,
114 EV_WRITEBUF,
115 EV_DATAIN,
116 EV_HANGUP,
117 EV_BC_REL,
118 EV_CINF,
119 };
120
121 #define EVENT_COUNT (EV_CINF+1)
122
123 static char *strEvent[] =
124 {
125 "EV_DIAL",
126 "EV_SETUP_CNF",
127 "EV_ACCEPTB",
128 "EV_DISCONNECT_CNF",
129 "EV_DISCONNECT_IND",
130 "EV_RELEASE_CNF",
131 "EV_DLEST",
132 "EV_DLRL",
133 "EV_SETUP_IND",
134 "EV_RELEASE_IND",
135 "EV_ACCEPTD",
136 "EV_SETUP_CMPL_IND",
137 "EV_BC_EST",
138 "EV_WRITEBUF",
139 "EV_DATAIN",
140 "EV_HANGUP",
141 "EV_BC_REL",
142 "EV_CINF",
143 };
144
145 enum {
146 ST_LC_NULL,
147 ST_LC_ACTIVATE_WAIT,
148 ST_LC_DELAY,
149 ST_LC_ESTABLISH_WAIT,
150 ST_LC_CONNECTED,
151 ST_LC_RELEASE_WAIT,
152 };
153
154 #define LC_STATE_COUNT (ST_LC_RELEASE_WAIT+1)
155
156 static char *strLcState[] =
157 {
158 "ST_LC_NULL",
159 "ST_LC_ACTIVATE_WAIT",
160 "ST_LC_DELAY",
161 "ST_LC_ESTABLISH_WAIT",
162 "ST_LC_CONNECTED",
163 "ST_LC_RELEASE_WAIT",
164 };
165
166 enum {
167 EV_LC_ESTABLISH,
168 EV_LC_PH_ACTIVATE,
169 EV_LC_PH_DEACTIVATE,
170 EV_LC_DL_ESTABLISH,
171 EV_LC_TIMER,
172 EV_LC_DL_RELEASE,
173 EV_LC_RELEASE,
174 };
175
176 #define LC_EVENT_COUNT (EV_LC_RELEASE+1)
177
178 static char *strLcEvent[] =
179 {
180 "EV_LC_ESTABLISH",
181 "EV_LC_PH_ACTIVATE",
182 "EV_LC_PH_DEACTIVATE",
183 "EV_LC_DL_ESTABLISH",
184 "EV_LC_TIMER",
185 "EV_LC_DL_RELEASE",
186 "EV_LC_RELEASE",
187 };
188
189 #define LC_D 0
190 #define LC_B 1
191
192 static int
193 my_atoi(char *s)
194 {
195 int i, n;
196
197 n = 0;
198 if (!s)
199 return -1;
200 for (i = 0; *s >= '0' && *s <= '9'; i++, s++)
201 n = 10 * n + (*s - '0');
202 return n;
203 }
204
205
206
207
208 static void
209 r1(struct FsmInst *fi, int event, void *arg)
210 {
211 isdn_ctrl *ic = arg;
212 struct Channel *chanp = fi->userdata;
213 char *ptr;
214 char sis[3];
215
216
217 ptr = strcpyupto(chanp->para.called, ic->num, ',');
218
219 ptr = strcpyupto(chanp->para.calling, ptr + 1, ',');
220 if (!strcmp(chanp->para.calling, "0"))
221 chanp->para.calling[0] = '\0';
222
223
224 ptr = strcpyupto(sis, ptr + 1, ',');
225 chanp->para.info = my_atoi(sis);
226
227
228 ptr = strcpyupto(sis, ptr + 1, '\0');
229 chanp->para.info2 = my_atoi(sis);
230
231 chanp->l2_active_protocol = chanp->l2_protocol;
232 chanp->incoming = 0;
233 chanp->lc_b.l2_start = !0;
234
235 switch (chanp->l2_active_protocol) {
236 case (ISDN_PROTO_L2_X75I):
237 chanp->lc_b.l2_establish = !0;
238 break;
239 case (ISDN_PROTO_L2_HDLC):
240 chanp->lc_b.l2_establish = 0;
241 break;
242 default:
243 printk(KERN_WARNING "r1 unknown protocol\n");
244 break;
245 }
246
247 FsmChangeState(fi, ST_OUT_W);
248 FsmEvent(&chanp->lc_d.lcfi, EV_LC_ESTABLISH, NULL);
249 }
250
251 static void
252 ll_hangup(struct Channel *chanp, int bchantoo)
253 {
254 isdn_ctrl ic;
255
256 if (bchantoo) {
257 if (chanp->debug & 1)
258 stat_debug(chanp, "STAT_BHUP");
259 ic.driver = drid;
260 ic.command = ISDN_STAT_BHUP;
261 ic.arg = chanp->chan;
262 iif.statcallb(&ic);
263 }
264 if (chanp->debug & 1)
265 stat_debug(chanp, "STAT_DHUP");
266 ic.driver = drid;
267 ic.command = ISDN_STAT_DHUP;
268 ic.arg = chanp->chan;
269 iif.statcallb(&ic);
270 }
271
272 static void
273 r2(struct FsmInst *fi, int event, void *arg)
274 {
275 struct Channel *chanp = fi->userdata;
276
277 chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
278
279 FsmChangeState(fi, ST_CLEAR);
280 ll_hangup(chanp, 0);
281 }
282
283
284 static void
285 r2_1(struct FsmInst *fi, int event, void *arg)
286 {
287 struct Channel *chanp = fi->userdata;
288
289 chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
290
291 FsmChangeState(fi, ST_OUT_W_HANGUP);
292 }
293
294
295 static void
296 r2_2(struct FsmInst *fi, int event, void *arg)
297 {
298 struct Channel *chanp = fi->userdata;
299
300 FsmChangeState(fi, ST_REL_W);
301 FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
302 ll_hangup(chanp, 0);
303 }
304
305
306 static void
307 r3(struct FsmInst *fi, int event, void *arg)
308 {
309 struct Channel *chanp = fi->userdata;
310
311 FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
312 FsmChangeState(fi, ST_REL_W);
313 }
314
315
316 static void
317 r3_1(struct FsmInst *fi, int event, void *arg)
318 {
319 struct Channel *chanp = fi->userdata;
320
321 chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
322
323 FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
324 FsmChangeState(fi, ST_REL_W);
325 ll_hangup(chanp, 0);
326 }
327
328
329 static void
330 r4(struct FsmInst *fi, int event, void *arg)
331 {
332 struct Channel *chanp=fi->userdata;
333
334 chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
335 FsmChangeState(fi, ST_NULL);
336 }
337
338 static void
339 r5(struct FsmInst *fi, int event, void *arg)
340 {
341 struct Channel *chanp = fi->userdata;
342
343 chanp->para.callref = chanp->outcallref;
344
345 chanp->outcallref++;
346 if (chanp->outcallref == 128)
347 chanp->outcallref = 64;
348
349 chanp->is.l4.l4l3(&chanp->is, CC_SETUP_REQ, NULL);
350
351 FsmChangeState(fi, ST_OUT);
352 }
353
354 static void
355 r6(struct FsmInst *fi, int event, void *arg)
356 {
357 struct Channel *chanp = fi->userdata;
358
359 FsmChangeState(fi, ST_IN_W);
360 FsmEvent(&chanp->lc_d.lcfi, EV_LC_ESTABLISH, NULL);
361 }
362
363 static void
364 r7(struct FsmInst *fi, int event, void *arg)
365 {
366 struct Channel *chanp = fi->userdata;
367 isdn_ctrl ic;
368
369
370
371
372
373
374 if (((chanp->chan & 1) + 1) & chanp->para.bchannel) {
375 chanp->is.l4.l4l3(&chanp->is, CC_ALERTING_REQ, NULL);
376 FsmChangeState(fi, ST_IN);
377 if (chanp->debug & 1)
378 stat_debug(chanp, "STAT_ICALL");
379 ic.driver = drid;
380 ic.command = ISDN_STAT_ICALL;
381 ic.arg = chanp->chan;
382
383
384
385
386 sprintf(ic.num, "%s,%d,0,%s", chanp->para.calling, chanp->para.info,
387 chanp->para.called);
388 iif.statcallb(&ic);
389 } else {
390 chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
391 FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
392 FsmChangeState(fi, ST_REL_W);
393 }
394 }
395
396 static void
397 r8(struct FsmInst *fi, int event, void *arg)
398 {
399 struct Channel *chanp = fi->userdata;
400
401 FsmChangeState(fi, ST_IN_SETUP);
402 chanp->is.l4.l4l3(&chanp->is, CC_SETUP_RSP, NULL);
403
404 }
405
406 static void
407 r9(struct FsmInst *fi, int event, void *arg)
408 {
409 struct Channel *chanp = fi->userdata;
410
411 FsmChangeState(fi, ST_IN_DACT);
412
413 chanp->l2_active_protocol = chanp->l2_protocol;
414 chanp->incoming = !0;
415 chanp->lc_b.l2_start = 0;
416
417 switch (chanp->l2_active_protocol) {
418 case (ISDN_PROTO_L2_X75I):
419 chanp->lc_b.l2_establish = !0;
420 break;
421 case (ISDN_PROTO_L2_HDLC):
422 chanp->lc_b.l2_establish = 0;
423 break;
424 default:
425 printk(KERN_WARNING "r9 unknown protocol\n");
426 break;
427 }
428
429 init_ds(chanp->chan, !0);
430
431 FsmEvent(&chanp->lc_b.lcfi, EV_LC_ESTABLISH, NULL);
432 }
433
434 static void
435 r10(struct FsmInst *fi, int event, void *arg)
436 {
437 struct Channel *chanp = fi->userdata;
438
439 FsmChangeState(fi, ST_OUT_ESTB);
440
441 init_ds(chanp->chan, 0);
442 FsmEvent(&chanp->lc_b.lcfi, EV_LC_ESTABLISH, NULL);
443
444 }
445
446 static void
447 r12(struct FsmInst *fi, int event, void *arg)
448 {
449 struct Channel *chanp = fi->userdata;
450 isdn_ctrl ic;
451
452 FsmChangeState(fi, ST_ACTIVE);
453 chanp->data_open = !0;
454
455 if (chanp->debug & 1)
456 stat_debug(chanp, "STAT_DCONN");
457 ic.driver = drid;
458 ic.command = ISDN_STAT_DCONN;
459 ic.arg = chanp->chan;
460 iif.statcallb(&ic);
461
462 if (chanp->debug & 1)
463 stat_debug(chanp, "STAT_BCONN");
464 ic.driver = drid;
465 ic.command = ISDN_STAT_BCONN;
466 ic.arg = chanp->chan;
467 iif.statcallb(&ic);
468 }
469
470 #ifdef DEFINED_BUT_NOT_USED
471 static void
472 prp(byte * p, int size)
473 {
474 while (size--)
475 printk("%2x ", *p++);
476 printk("\n");
477 }
478 #endif
479
480 static void
481 r15(struct FsmInst *fi, int event, void *arg)
482 {
483 struct Channel *chanp = fi->userdata;
484
485 chanp->data_open = 0;
486 FsmChangeState(fi, ST_BC_HANGUP);
487 FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
488 }
489
490 static void
491 r16(struct FsmInst *fi, int event, void *arg)
492 {
493 struct Channel *chanp = fi->userdata;
494
495 release_ds(chanp->chan);
496
497 FsmChangeState(fi, ST_PRO_W);
498 chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
499 }
500
501 static void
502 r17(struct FsmInst *fi, int event, void *arg)
503 {
504 struct Channel *chanp = fi->userdata;
505
506 chanp->data_open = 0;
507 release_ds(chanp->chan);
508
509 FsmChangeState(fi, ST_ANT_W);
510 }
511
512
513 static void
514 r17_1(struct FsmInst *fi, int event, void *arg)
515 {
516 struct Channel *chanp = fi->userdata;
517
518 chanp->data_open = 0;
519 release_ds(chanp->chan);
520
521 chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
522
523 FsmEvent(&chanp->lc_d.lcfi,EV_LC_RELEASE,NULL);
524
525 FsmChangeState(fi, ST_NULL);
526
527 ll_hangup(chanp,!0);
528 }
529
530 static void
531 r18(struct FsmInst *fi, int event, void *arg)
532 {
533 struct Channel *chanp = fi->userdata;
534
535 FsmChangeState(fi, ST_REL_W);
536 FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
537
538 ll_hangup(chanp, !0);
539 }
540
541 static void
542 r19(struct FsmInst *fi, int event, void *arg)
543 {
544 struct Channel *chanp = fi->userdata;
545
546 FsmChangeState(fi, ST_CLEAR);
547
548 chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
549
550 ll_hangup(chanp, !0);
551 }
552
553 static void
554 r20(struct FsmInst *fi, int event, void *arg)
555 {
556 struct Channel *chanp = fi->userdata;
557
558 chanp->is.l4.l4l3(&chanp->is,CC_DLRL,NULL);
559
560 FsmEvent(&chanp->lc_d.lcfi,EV_LC_RELEASE,NULL);
561
562 FsmChangeState(fi, ST_NULL);
563
564 ll_hangup(chanp, 0);
565 }
566
567
568 static void
569 r21(struct FsmInst *fi, int event, void *arg)
570 {
571 struct Channel *chanp = fi->userdata;
572
573 chanp->data_open = 0;
574 FsmChangeState(fi, ST_DISC_BC_HANGUP);
575 FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
576 }
577
578 static void
579 r22(struct FsmInst *fi, int event, void *arg)
580 {
581 struct Channel *chanp = fi->userdata;
582
583 release_ds(chanp->chan);
584
585 FsmChangeState(fi, ST_CLEAR);
586
587 chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
588
589 ll_hangup(chanp, !0);
590 }
591
592 static void
593 r23(struct FsmInst *fi, int event, void *arg)
594 {
595 struct Channel *chanp = fi->userdata;
596
597 release_ds(chanp->chan);
598
599 FsmChangeState(fi, ST_PRO_W);
600 chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
601 }
602
603 static void
604 r23_1(struct FsmInst *fi, int event, void *arg)
605 {
606 struct Channel *chanp = fi->userdata;
607
608 release_ds(chanp->chan);
609
610 chanp->is.l4.l4l3(&chanp->is, CC_DLRL,NULL);
611
612 FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE,NULL);
613
614 FsmChangeState(fi, ST_NULL);
615
616 ll_hangup(chanp,!0);
617 }
618
619 static void
620 r24(struct FsmInst *fi, int event, void *arg)
621 {
622 struct Channel *chanp = fi->userdata;
623
624 chanp->data_open = 0;
625 FsmChangeState(fi, ST_D_ERR);
626 FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
627 }
628
629 static void
630 r25(struct FsmInst *fi, int event, void *arg)
631 {
632 struct Channel *chanp = fi->userdata;
633
634 release_ds(chanp->chan);
635
636 FsmChangeState(fi, ST_NULL);
637
638 ll_hangup(chanp, !0);
639 }
640
641 static void
642 r26(struct FsmInst *fi, int event, void *arg)
643 {
644 struct Channel *chanp = fi->userdata;
645 isdn_ctrl ic;
646
647
648 ic.driver = drid;
649 ic.command = ISDN_STAT_CINF;
650 ic.arg = chanp->chan;
651 sprintf(ic.num, "%d", chanp->para.chargeinfo);
652 iif.statcallb(&ic);
653 }
654
655
656
657 static struct FsmNode fnlist[] =
658 {
659 {ST_NULL, EV_DIAL, r1},
660 {ST_OUT_W, EV_DLEST, r5},
661 {ST_OUT_W, EV_DLRL, r20},
662 {ST_OUT_W, EV_RELEASE_CNF, r2_2 },
663 {ST_OUT, EV_DISCONNECT_IND, r2},
664 {ST_OUT, EV_SETUP_CNF, r10},
665 {ST_OUT, EV_HANGUP, r2_1},
666 {ST_OUT, EV_RELEASE_IND, r20},
667 {ST_OUT, EV_DLRL, r2_2},
668 {ST_OUT_W_HANGUP, EV_RELEASE_IND, r2_2},
669 {ST_OUT_W_HANGUP, EV_DLRL, r20},
670 {ST_CLEAR, EV_RELEASE_CNF, r3},
671 {ST_CLEAR, EV_DLRL, r20},
672 {ST_REL_W, EV_DLRL, r4},
673 {ST_NULL, EV_SETUP_IND, r6},
674 {ST_IN_W, EV_DLEST, r7},
675 {ST_IN_W, EV_DLRL, r3_1},
676 {ST_IN, EV_DLRL, r3_1},
677 {ST_IN, EV_HANGUP, r3_1},
678 {ST_IN, EV_RELEASE_IND, r2_2},
679 {ST_IN, EV_RELEASE_CNF, r2_2},
680 {ST_IN, EV_ACCEPTD, r8},
681 {ST_IN_SETUP, EV_HANGUP, r2_1},
682 {ST_IN_SETUP, EV_SETUP_CMPL_IND, r9},
683 {ST_IN_SETUP, EV_RELEASE_IND, r2_2},
684 {ST_IN_SETUP, EV_DISCONNECT_IND, r2},
685 {ST_IN_SETUP, EV_DLRL, r20},
686 {ST_OUT_ESTB, EV_BC_EST, r12},
687 {ST_OUT_ESTB, EV_BC_REL, r23},
688 {ST_OUT_ESTB, EV_DLRL, r23_1},
689 {ST_IN_DACT, EV_BC_EST, r12},
690 {ST_IN_DACT, EV_BC_REL, r17},
691 {ST_IN_DACT, EV_DLRL, r17_1},
692 {ST_ACTIVE, EV_HANGUP, r15},
693 {ST_ACTIVE, EV_BC_REL, r17},
694 {ST_ACTIVE, EV_DISCONNECT_IND, r21},
695 {ST_ACTIVE, EV_DLRL, r24},
696 {ST_ACTIVE, EV_CINF, r26},
697 {ST_ACTIVE, EV_RELEASE_IND, r17},
698 {ST_BC_HANGUP, EV_BC_REL, r16},
699 {ST_BC_HANGUP, EV_DISCONNECT_IND, r21},
700 {ST_PRO_W, EV_RELEASE_IND, r18},
701 {ST_ANT_W, EV_DISCONNECT_IND, r19},
702 {ST_DISC_BC_HANGUP, EV_BC_REL, r22},
703 {ST_D_ERR, EV_BC_REL, r25},
704 };
705
706 #define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
707
708 static void
709 lc_r1(struct FsmInst *fi, int event, void *arg)
710 {
711 struct LcFsm *lf = fi->userdata;
712
713 FsmChangeState(fi, ST_LC_ACTIVATE_WAIT);
714 FsmAddTimer(&lf->act_timer, 1000, EV_LC_TIMER, NULL, 50);
715 lf->st->ma.manl1(lf->st, PH_ACTIVATE, NULL);
716
717 }
718
719 static void
720 lc_r6(struct FsmInst *fi, int event, void *arg)
721 {
722 struct LcFsm *lf = fi->userdata;
723
724 FsmDelTimer(&lf->act_timer, 50);
725 FsmChangeState(fi, ST_LC_DELAY);
726 FsmAddTimer(&lf->act_timer, 40, EV_LC_TIMER, NULL, 51);
727 }
728
729 static void
730 lc_r2(struct FsmInst *fi, int event, void *arg)
731 {
732 struct LcFsm *lf = fi->userdata;
733
734 if (lf->l2_establish) {
735 FsmChangeState(fi, ST_LC_ESTABLISH_WAIT);
736 if (lf->l2_start)
737 lf->st->ma.manl2(lf->st, DL_ESTABLISH, NULL);
738 } else {
739 FsmChangeState(fi, ST_LC_CONNECTED);
740 lf->lccall(lf, LC_ESTABLISH, NULL);
741 }
742 }
743
744 static void
745 lc_r3(struct FsmInst *fi, int event, void *arg)
746 {
747 struct LcFsm *lf = fi->userdata;
748
749 FsmChangeState(fi, ST_LC_CONNECTED);
750 lf->lccall(lf, LC_ESTABLISH, NULL);
751 }
752
753 static void
754 lc_r4(struct FsmInst *fi, int event, void *arg)
755 {
756 struct LcFsm *lf = fi->userdata;
757
758 if (lf->l2_establish) {
759 FsmChangeState(fi, ST_LC_RELEASE_WAIT);
760 lf->st->ma.manl2(lf->st, DL_RELEASE, NULL);
761 } else {
762 FsmChangeState(fi, ST_LC_NULL);
763 lf->st->ma.manl1(lf->st, PH_DEACTIVATE, NULL);
764 lf->lccall(lf, LC_RELEASE, NULL);
765 }
766 }
767
768 static void
769 lc_r5(struct FsmInst *fi, int event, void *arg)
770 {
771 struct LcFsm *lf = fi->userdata;
772
773 FsmChangeState(fi, ST_LC_NULL);
774 lf->st->ma.manl1(lf->st, PH_DEACTIVATE, NULL);
775 lf->lccall(lf, LC_RELEASE, NULL);
776 }
777
778 static struct FsmNode LcFnList[] =
779 {
780 {ST_LC_NULL, EV_LC_ESTABLISH, lc_r1},
781 {ST_LC_ACTIVATE_WAIT, EV_LC_PH_ACTIVATE, lc_r6},
782 {ST_LC_DELAY, EV_LC_TIMER, lc_r2},
783 {ST_LC_ESTABLISH_WAIT, EV_LC_DL_ESTABLISH, lc_r3},
784 {ST_LC_CONNECTED, EV_LC_RELEASE, lc_r4},
785 {ST_LC_CONNECTED, EV_LC_DL_RELEASE, lc_r5},
786 {ST_LC_RELEASE_WAIT, EV_LC_DL_RELEASE, lc_r5},
787 {ST_LC_ACTIVATE_WAIT, EV_LC_TIMER, lc_r5},
788 {ST_LC_ESTABLISH_WAIT, EV_LC_DL_RELEASE, lc_r5},
789 };
790
791 #define LC_FN_COUNT (sizeof(LcFnList)/sizeof(struct FsmNode))
792
793 void
794 CallcNew(void)
795 {
796 callcfsm.state_count = STATE_COUNT;
797 callcfsm.event_count = EVENT_COUNT;
798 callcfsm.strEvent = strEvent;
799 callcfsm.strState = strState;
800 FsmNew(&callcfsm, fnlist, FNCOUNT);
801
802 lcfsm.state_count = LC_STATE_COUNT;
803 lcfsm.event_count = LC_EVENT_COUNT;
804 lcfsm.strEvent = strLcEvent;
805 lcfsm.strState = strLcState;
806 FsmNew(&lcfsm, LcFnList, LC_FN_COUNT);
807 }
808
809 void
810 CallcFree(void)
811 {
812 FsmFree(&lcfsm);
813 FsmFree(&callcfsm);
814 }
815
816 static void
817 release_ds(int chan)
818 {
819 struct PStack *st = &chanlist[chan].ds;
820 struct IsdnCardState *sp;
821 struct HscxState *hsp;
822
823 sp = st->l1.hardware;
824 hsp = sp->hs + chanlist[chan].hscx;
825
826 close_hscxstate(hsp);
827
828 switch (chanlist[chan].l2_active_protocol) {
829 case (ISDN_PROTO_L2_X75I):
830 releasestack_isdnl2(st);
831 break;
832 case (ISDN_PROTO_L2_HDLC):
833 releasestack_transl2(st);
834 break;
835 }
836 }
837
838 static void
839 cc_l1man(struct PStack *st, int pr, void *arg)
840 {
841 struct Channel *chanp = (struct Channel *) st->l4.userdata;
842
843 switch (pr) {
844 case (PH_ACTIVATE):
845 FsmEvent(&chanp->lc_d.lcfi, EV_LC_PH_ACTIVATE, NULL);
846 break;
847 case (PH_DEACTIVATE):
848 FsmEvent(&chanp->lc_d.lcfi, EV_LC_PH_DEACTIVATE, NULL);
849 break;
850 }
851 }
852
853 static void
854 cc_l2man(struct PStack *st, int pr, void *arg)
855 {
856 struct Channel *chanp = (struct Channel *) st->l4.userdata;
857
858 switch (pr) {
859 case (DL_ESTABLISH):
860 FsmEvent(&chanp->lc_d.lcfi, EV_LC_DL_ESTABLISH, NULL);
861 break;
862 case (DL_RELEASE):
863 FsmEvent(&chanp->lc_d.lcfi, EV_LC_DL_RELEASE, NULL);
864 break;
865 }
866 }
867
868 static void
869 dcc_l1man(struct PStack *st, int pr, void *arg)
870 {
871 struct Channel *chanp = (struct Channel *) st->l4.userdata;
872
873 switch (pr) {
874 case (PH_ACTIVATE):
875 FsmEvent(&chanp->lc_b.lcfi, EV_LC_PH_ACTIVATE, NULL);
876 break;
877 case (PH_DEACTIVATE):
878 FsmEvent(&chanp->lc_b.lcfi, EV_LC_PH_DEACTIVATE, NULL);
879 break;
880 }
881 }
882
883 static void
884 dcc_l2man(struct PStack *st, int pr, void *arg)
885 {
886 struct Channel *chanp = (struct Channel *) st->l4.userdata;
887
888 switch (pr) {
889 case (DL_ESTABLISH):
890 FsmEvent(&chanp->lc_b.lcfi, EV_LC_DL_ESTABLISH, NULL);
891 break;
892 case (DL_RELEASE):
893 FsmEvent(&chanp->lc_b.lcfi, EV_LC_DL_RELEASE, NULL);
894 break;
895 }
896 }
897
898 static void
899 ll_handler(struct PStack *st, int pr,
900 struct BufHeader *ibh)
901 {
902 struct Channel *chanp = (struct Channel *) st->l4.userdata;
903
904 switch (pr) {
905 case (CC_DISCONNECT_IND):
906 FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL);
907 break;
908 case (CC_RELEASE_CNF):
909 FsmEvent(&chanp->fi, EV_RELEASE_CNF, NULL);
910 break;
911 case (CC_SETUP_IND):
912 FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
913 break;
914 case (CC_RELEASE_IND):
915 FsmEvent(&chanp->fi, EV_RELEASE_IND, NULL);
916 break;
917 case (CC_SETUP_COMPLETE_IND):
918 FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL);
919 break;
920 case (CC_SETUP_CNF):
921 FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
922 break;
923 case (CC_INFO_CHARGE):
924 FsmEvent(&chanp->fi, EV_CINF, NULL);
925 break;
926 }
927 }
928
929 static void
930 init_is(int chan, unsigned int ces)
931 {
932 struct PStack *st = &(chanlist[chan].is);
933 struct IsdnCardState *sp = chanlist[chan].sp;
934 char tmp[128];
935
936 setstack_teles(st, sp);
937
938 st->l2.sap = 0;
939
940 st->l2.tei = 255;
941
942 st->l2.ces = ces;
943 st->l2.extended = !0;
944 st->l2.laptype = LAPD;
945 st->l2.window = 1;
946 st->l2.orig = !0;
947 st->l2.t200 = 1000;
948 if (st->protocol == ISDN_PTYPE_1TR6) {
949 st->l2.n200 = 3;
950 st->l2.t203 = 10000;
951 } else {
952 st->l2.n200 = 4;
953 st->l2.t203 = 5000;
954 }
955
956 sprintf(tmp, "Channel %d q.921", chan);
957 setstack_isdnl2(st, tmp);
958 setstack_isdnl3(st);
959 st->l2.debug = 2;
960 st->l3.debug = 2;
961 st->l2.debug = 0xff;
962 st->l3.debug = 0xff;
963 st->l4.userdata = chanlist + chan;
964 st->l4.l2writewakeup = NULL;
965
966 st->l3.l3l4 = ll_handler;
967 st->l1.l1man = cc_l1man;
968 st->l2.l2man = cc_l2man;
969
970 st->pa = &chanlist[chan].para;
971 teles_addlist(sp, st);
972 }
973
974 static void
975 callc_debug(struct FsmInst *fi, char *s)
976 {
977 char str[80], tm[32];
978 struct Channel *chanp = fi->userdata;
979
980 jiftime(tm, jiffies);
981 sprintf(str, "%s Channel %d callc %s\n", tm, chanp->chan, s);
982 teles_putstatus(str);
983 }
984
985 static void
986 lc_debug(struct FsmInst *fi, char *s)
987 {
988 char str[256], tm[32];
989 struct LcFsm *lf = fi->userdata;
990
991 jiftime(tm, jiffies);
992 sprintf(str, "%s Channel %d lc %s\n", tm, lf->ch->chan, s);
993 teles_putstatus(str);
994 }
995
996 static void
997 dlc_debug(struct FsmInst *fi, char *s)
998 {
999 char str[256], tm[32];
1000 struct LcFsm *lf = fi->userdata;
1001
1002 jiftime(tm, jiffies);
1003 sprintf(str, "%s Channel %d dlc %s\n", tm, lf->ch->chan, s);
1004 teles_putstatus(str);
1005 }
1006
1007 static void
1008 lccall_d(struct LcFsm *lf, int pr, void *arg)
1009 {
1010 struct Channel *chanp = lf->ch;
1011
1012 switch (pr) {
1013 case (LC_ESTABLISH):
1014 FsmEvent(&chanp->fi, EV_DLEST, NULL);
1015 break;
1016 case (LC_RELEASE):
1017 FsmEvent(&chanp->fi, EV_DLRL, NULL);
1018 break;
1019 }
1020 }
1021
1022 static void
1023 lccall_b(struct LcFsm *lf, int pr, void *arg)
1024 {
1025 struct Channel *chanp = lf->ch;
1026
1027 switch (pr) {
1028 case (LC_ESTABLISH):
1029 FsmEvent(&chanp->fi, EV_BC_EST, NULL);
1030 break;
1031 case (LC_RELEASE):
1032 FsmEvent(&chanp->fi, EV_BC_REL, NULL);
1033 break;
1034 }
1035 }
1036
1037 static void
1038 init_chan(int chan, int cardnr, int hscx,
1039 unsigned int ces)
1040 {
1041 struct IsdnCard *card = cards + cardnr;
1042 struct Channel *chanp = chanlist + chan;
1043
1044 chanp->sp = card->sp;
1045 chanp->hscx = hscx;
1046 chanp->chan = chan;
1047 chanp->incoming = 0;
1048 chanp->debug = 0;
1049 init_is(chan, ces);
1050
1051 chanp->fi.fsm = &callcfsm;
1052 chanp->fi.state = ST_NULL;
1053 chanp->fi.debug = 0;
1054 chanp->fi.userdata = chanp;
1055 chanp->fi.printdebug = callc_debug;
1056
1057 chanp->lc_d.lcfi.fsm = &lcfsm;
1058 chanp->lc_d.lcfi.state = ST_LC_NULL;
1059 chanp->lc_d.lcfi.debug = 0;
1060 chanp->lc_d.lcfi.userdata = &chanp->lc_d;
1061 chanp->lc_d.lcfi.printdebug = lc_debug;
1062 chanp->lc_d.type = LC_D;
1063 chanp->lc_d.ch = chanp;
1064 chanp->lc_d.st = &chanp->is;
1065 chanp->lc_d.l2_establish = !0;
1066 chanp->lc_d.l2_start = !0;
1067 chanp->lc_d.lccall = lccall_d;
1068 FsmInitTimer(&chanp->lc_d.lcfi, &chanp->lc_d.act_timer);
1069
1070 chanp->lc_b.lcfi.fsm = &lcfsm;
1071 chanp->lc_b.lcfi.state = ST_LC_NULL;
1072 chanp->lc_b.lcfi.debug = 0;
1073 chanp->lc_b.lcfi.userdata = &chanp->lc_b;
1074 chanp->lc_b.lcfi.printdebug = dlc_debug;
1075 chanp->lc_b.type = LC_B;
1076 chanp->lc_b.ch = chanp;
1077 chanp->lc_b.st = &chanp->ds;
1078 chanp->lc_b.l2_establish = !0;
1079 chanp->lc_b.l2_start = !0;
1080 chanp->lc_b.lccall = lccall_b;
1081 FsmInitTimer(&chanp->lc_b.lcfi, &chanp->lc_b.act_timer);
1082
1083 chanp->outcallref = 64;
1084 chanp->data_open = 0;
1085 }
1086
1087 int
1088 CallcNewChan(void)
1089 {
1090 int i, ces, c;
1091
1092 chancount = 0;
1093 for (i = 0; i < nrcards; i++)
1094 if (cards[i].sp)
1095 chancount += 2;
1096
1097 chanlist = (struct Channel *) Smalloc(sizeof(struct Channel) *
1098 chancount, GFP_KERNEL, "chanlist");
1099
1100 c = 0;
1101 ces = randomces();
1102 for (i = 0; i < nrcards; i++)
1103 if (cards[i].sp) {
1104 init_chan(c++, i, 1, ces++);
1105 ces %= 0xffff;
1106 init_chan(c++, i, 0, ces++);
1107 ces %= 0xffff;
1108 }
1109 printk(KERN_INFO "channels %d\n", chancount);
1110 return (chancount);
1111
1112 }
1113
1114 static void
1115 release_is(int chan)
1116 {
1117 struct PStack *st = &chanlist[chan].is;
1118
1119 releasestack_isdnl2(st);
1120 teles_rmlist(st->l1.hardware, st);
1121 BufQueueRelease(&st->l2.i_queue);
1122 }
1123
1124 static void
1125 release_chan(int chan)
1126 {
1127 #if 0
1128 release_ds(chan);
1129 #endif
1130 release_is(chan);
1131 }
1132
1133 void
1134 CallcFreeChan(void)
1135 {
1136 int i;
1137
1138 for (i = 0; i < chancount; i++)
1139 release_chan(i);
1140 Sfree((void *) chanlist);
1141 }
1142
1143 static void
1144 lldata_handler(struct PStack *st, int pr,
1145 void *arg)
1146 {
1147 struct Channel *chanp = (struct Channel *) st->l4.userdata;
1148 byte *ptr;
1149 int size;
1150 struct BufHeader *ibh = arg;
1151
1152 switch (pr) {
1153 case (DL_DATA):
1154 if (chanp->data_open) {
1155 ptr = DATAPTR(ibh);
1156 ptr += chanp->ds.l2.ihsize;
1157 size = ibh->datasize - chanp->ds.l2.ihsize;
1158 iif.rcvcallb(drid, chanp->chan, ptr, size);
1159 }
1160 BufPoolRelease(ibh);
1161 break;
1162 default:
1163 printk(KERN_WARNING "lldata_handler unknown primitive\n");
1164 break;
1165 }
1166 }
1167
1168 static void
1169 lltrans_handler(struct PStack *st, int pr,
1170 struct BufHeader *ibh)
1171 {
1172 struct Channel *chanp = (struct Channel *) st->l4.userdata;
1173 byte *ptr;
1174
1175 switch (pr) {
1176 case (PH_DATA):
1177 if (chanp->data_open) {
1178 ptr = DATAPTR(ibh);
1179 iif.rcvcallb(drid, chanp->chan, ptr, ibh->datasize);
1180 }
1181 BufPoolRelease(ibh);
1182 break;
1183 default:
1184 printk(KERN_WARNING "lltrans_handler unknown primitive\n");
1185 break;
1186 }
1187 }
1188
1189 static void
1190 ll_writewakeup(struct PStack *st)
1191 {
1192 struct Channel *chanp = st->l4.userdata;
1193 isdn_ctrl ic;
1194
1195 ic.driver = drid;
1196 ic.command = ISDN_STAT_BSENT;
1197 ic.arg = chanp->chan;
1198 iif.statcallb(&ic);
1199 }
1200
1201 static int
1202 init_ds(int chan, int incoming)
1203 {
1204 struct PStack *st = &(chanlist[chan].ds);
1205 struct IsdnCardState *sp = (struct IsdnCardState *)
1206 chanlist[chan].is.l1.hardware;
1207 struct HscxState *hsp = sp->hs + chanlist[chan].hscx;
1208 char tmp[128];
1209
1210 st->l1.hardware = sp;
1211
1212 hsp->mode = 2;
1213 hsp->transbufsize = 4000;
1214
1215 if (setstack_hscx(st, hsp))
1216 return (-1);
1217
1218 st->l2.extended = 0;
1219 st->l2.laptype = LAPB;
1220 st->l2.orig = !incoming;
1221 st->l2.t200 = 1000;
1222 st->l2.window = 3;
1223 st->l2.n200 = 4;
1224 st->l2.t203 = 5000;
1225
1226 st->l2.debug = 0xff;
1227 st->l3.debug = 0xff;
1228 switch (chanlist[chan].l2_active_protocol) {
1229 case (ISDN_PROTO_L2_X75I):
1230 sprintf(tmp, "Channel %d x.75", chan);
1231 setstack_isdnl2(st, tmp);
1232 st->l2.l2l3 = lldata_handler;
1233 st->l1.l1man = dcc_l1man;
1234 st->l2.l2man = dcc_l2man;
1235 st->l4.userdata = chanlist + chan;
1236 st->l4.l1writewakeup = NULL;
1237 st->l4.l2writewakeup = ll_writewakeup;
1238 st->l2.l2m.debug = debugflags & 16;
1239 st->ma.manl2(st, MDL_NOTEIPROC, NULL);
1240 st->l1.hscxmode = 2;
1241 st->l1.hscxchannel = chanlist[chan].para.bchannel - 1;
1242 break;
1243 case (ISDN_PROTO_L2_HDLC):
1244 st->l1.l1l2 = lltrans_handler;
1245 st->l1.l1man = dcc_l1man;
1246 st->l4.userdata = chanlist + chan;
1247 st->l4.l1writewakeup = ll_writewakeup;
1248 st->l1.hscxmode = 2;
1249 st->l1.hscxchannel = chanlist[chan].para.bchannel - 1;
1250 break;
1251 }
1252
1253 return (0);
1254
1255 }
1256
1257 static void
1258 channel_report(int i)
1259 {
1260 }
1261
1262 static void
1263 command_debug(struct Channel *chanp, char *s)
1264 {
1265 char tmp[64], tm[32];
1266
1267 jiftime(tm, jiffies);
1268 sprintf(tmp, "%s Channel %d LL->HL %s\n", tm, chanp->chan, s);
1269 teles_putstatus(tmp);
1270 }
1271
1272 static void
1273 distr_debug(void)
1274 {
1275 int i;
1276
1277 for (i = 0; i < chancount; i++) {
1278 chanlist[i].debug = debugflags & 1;
1279 chanlist[i].fi.debug = debugflags & 2;
1280 chanlist[i].is.l2.l2m.debug = debugflags & 8;
1281 chanlist[i].ds.l2.l2m.debug = debugflags & 16;
1282 }
1283 for (i = 0; i < nrcards; i++)
1284 if (cards[i].sp)
1285 cards[i].sp->dlogflag = debugflags & 4;
1286 }
1287
1288 int
1289 teles_command(isdn_ctrl * ic)
1290 {
1291 struct Channel *chanp;
1292 char tmp[64];
1293 int i;
1294 unsigned int num;
1295
1296 switch (ic->command) {
1297 case (ISDN_CMD_SETEAZ):
1298 chanp = chanlist + ic->arg;
1299 if (chanp->debug & 1)
1300 command_debug(chanp, "SETEAZ");
1301 return (0);
1302 case (ISDN_CMD_DIAL):
1303 chanp = chanlist + (ic->arg & 0xff);
1304 if (chanp->debug & 1) {
1305 sprintf(tmp, "DIAL %s", ic->num);
1306 command_debug(chanp, tmp);
1307 }
1308 FsmEvent(&chanp->fi, EV_DIAL, ic);
1309 return (0);
1310 case (ISDN_CMD_ACCEPTB):
1311 chanp = chanlist + ic->arg;
1312 if (chanp->debug & 1)
1313 command_debug(chanp, "ACCEPTB");
1314 FsmEvent(&chanp->fi, EV_ACCEPTB, NULL);
1315 break;
1316 case (ISDN_CMD_ACCEPTD):
1317 chanp = chanlist + ic->arg;
1318 if (chanp->debug & 1)
1319 command_debug(chanp, "ACCEPTD");
1320 FsmEvent(&chanp->fi, EV_ACCEPTD, NULL);
1321 break;
1322 case (ISDN_CMD_HANGUP):
1323 chanp = chanlist + ic->arg;
1324 if (chanp->debug & 1)
1325 command_debug(chanp, "HANGUP");
1326 FsmEvent(&chanp->fi, EV_HANGUP, NULL);
1327 break;
1328 case (ISDN_CMD_LOCK):
1329 teles_mod_inc_use_count();
1330 break;
1331 case (ISDN_CMD_UNLOCK):
1332 teles_mod_dec_use_count();
1333 break;
1334 case (ISDN_CMD_IOCTL):
1335 switch (ic->arg) {
1336 case (0):
1337 for (i = 0; i < nrcards; i++)
1338 if (cards[i].sp)
1339 teles_reportcard(i);
1340 for (i = 0; i < chancount; i++)
1341 channel_report(i);
1342 break;
1343 case (1):
1344 debugflags = *(unsigned int *) ic->num;
1345 distr_debug();
1346 sprintf(tmp, "debugging flags set to %x\n", debugflags);
1347 teles_putstatus(tmp);
1348 break;
1349 case (2):
1350 num = *(unsigned int *) ic->num;
1351 i = num >> 8;
1352 if (i >= chancount)
1353 break;
1354 chanp = chanlist + i;
1355 chanp->impair = num & 0xff;
1356 if (chanp->debug & 1) {
1357 sprintf(tmp, "IMPAIR %x", chanp->impair);
1358 command_debug(chanp, tmp);
1359 }
1360 break;
1361 }
1362 break;
1363 case (ISDN_CMD_SETL2):
1364 chanp = chanlist + (ic->arg & 0xff);
1365 if (chanp->debug & 1) {
1366 sprintf(tmp, "SETL2 %ld", ic->arg >> 8);
1367 command_debug(chanp, tmp);
1368 }
1369 chanp->l2_protocol = ic->arg >> 8;
1370 break;
1371 default:
1372 break;
1373 }
1374
1375 return (0);
1376 }
1377
1378 int
1379 teles_writebuf(int id, int chan, const u_char * buf, int count, int user)
1380 {
1381 struct Channel *chanp = chanlist + chan;
1382 struct PStack *st = &chanp->ds;
1383 struct BufHeader *ibh;
1384 int err, i;
1385 byte *ptr;
1386
1387 err = BufPoolGet(&ibh, st->l1.sbufpool, GFP_ATOMIC, st, 21);
1388 if (err)
1389 return (0);
1390
1391 ptr = DATAPTR(ibh);
1392 if (chanp->lc_b.l2_establish)
1393 i = st->l2.ihsize;
1394 else
1395 i = 0;
1396
1397 if ((count+i) > BUFFER_SIZE(HSCX_SBUF_ORDER, HSCX_SBUF_BPPS)) {
1398 printk(KERN_WARNING "teles_writebuf: packet too large!\n");
1399 return (-EINVAL);
1400 }
1401
1402 ptr += i;
1403
1404 if (user)
1405 memcpy_fromfs(ptr, buf, count);
1406 else
1407 memcpy(ptr, buf, count);
1408 ibh->datasize = count + i;
1409
1410 if (chanp->data_open) {
1411 if (chanp->lc_b.l2_establish)
1412 chanp->ds.l3.l3l2(&chanp->ds, DL_DATA, ibh);
1413 else
1414 chanp->ds.l2.l2l1(&chanp->ds, PH_DATA, ibh);
1415 return (count);
1416 } else {
1417 BufPoolRelease(ibh);
1418 return (0);
1419 }
1420
1421 }
1422
1423 static char *
1424 strcpyupto(char *dest, char *src, char upto)
1425 {
1426 while (*src && (*src != upto) && (*src != '\0'))
1427 *dest++ = *src++;
1428 *dest = '\0';
1429 return (src);
1430 }