Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
maintidi.c
Go to the documentation of this file.
1 /*
2  *
3  Copyright (c) Eicon Networks, 2000.
4  *
5  This source file is supplied for the use with
6  Eicon Networks range of DIVA Server Adapters.
7  *
8  Eicon File Revision : 1.9
9  *
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2, or (at your option)
13  any later version.
14  *
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
17  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18  See the GNU General Public License for more details.
19  *
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 #include "platform.h"
26 #include "kst_ifc.h"
27 #include "di_defs.h"
28 #include "maintidi.h"
29 #include "pc.h"
30 #include "man_defs.h"
31 
32 
33 extern void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);
34 
35 #define MODEM_PARSE_ENTRIES 16 /* amount of variables of interest */
36 #define FAX_PARSE_ENTRIES 12 /* amount of variables of interest */
37 #define LINE_PARSE_ENTRIES 15 /* amount of variables of interest */
38 #define STAT_PARSE_ENTRIES 70 /* amount of variables of interest */
39 
40 /*
41  LOCAL FUNCTIONS
42 */
43 static int DivaSTraceLibraryStart(void *hLib);
44 static int DivaSTraceLibraryStop(void *hLib);
45 static int SuperTraceLibraryFinit(void *hLib);
46 static void *SuperTraceGetHandle(void *hLib);
47 static int SuperTraceMessageInput(void *hLib);
48 static int SuperTraceSetAudioTap(void *hLib, int Channel, int on);
49 static int SuperTraceSetBChannel(void *hLib, int Channel, int on);
50 static int SuperTraceSetDChannel(void *hLib, int on);
51 static int SuperTraceSetInfo(void *hLib, int on);
52 static int SuperTraceClearCall(void *hLib, int Channel);
53 static int SuperTraceGetOutgoingCallStatistics(void *hLib);
54 static int SuperTraceGetIncomingCallStatistics(void *hLib);
55 static int SuperTraceGetModemStatistics(void *hLib);
56 static int SuperTraceGetFaxStatistics(void *hLib);
57 static int SuperTraceGetBLayer1Statistics(void *hLib);
58 static int SuperTraceGetBLayer2Statistics(void *hLib);
59 static int SuperTraceGetDLayer1Statistics(void *hLib);
60 static int SuperTraceGetDLayer2Statistics(void *hLib);
61 
62 /*
63  LOCAL FUNCTIONS
64 */
65 static int ScheduleNextTraceRequest(diva_strace_context_t *pLib);
66 static int process_idi_event(diva_strace_context_t *pLib,
67  diva_man_var_header_t *pVar);
68 static int process_idi_info(diva_strace_context_t *pLib,
69  diva_man_var_header_t *pVar);
70 static int diva_modem_event(diva_strace_context_t *pLib, int Channel);
71 static int diva_fax_event(diva_strace_context_t *pLib, int Channel);
72 static int diva_line_event(diva_strace_context_t *pLib, int Channel);
73 static int diva_modem_info(diva_strace_context_t *pLib,
74  int Channel,
75  diva_man_var_header_t *pVar);
76 static int diva_fax_info(diva_strace_context_t *pLib,
77  int Channel,
78  diva_man_var_header_t *pVar);
79 static int diva_line_info(diva_strace_context_t *pLib,
80  int Channel,
81  diva_man_var_header_t *pVar);
82 static int diva_ifc_statistics(diva_strace_context_t *pLib,
83  diva_man_var_header_t *pVar);
84 static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar);
85 static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
86  const char *name);
87 static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var);
88 static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var);
89 static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var);
90 static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var);
91 static int diva_strace_read_ie(diva_man_var_header_t *pVar,
92  diva_trace_ie_t *var);
93 static void diva_create_parse_table(diva_strace_context_t *pLib);
94 static void diva_trace_error(diva_strace_context_t *pLib,
95  int error, const char *file, int line);
96 static void diva_trace_notify_user(diva_strace_context_t *pLib,
97  int Channel,
98  int notify_subject);
99 static int diva_trace_read_variable(diva_man_var_header_t *pVar,
100  void *variable);
101 
102 /*
103  Initialize the library and return context
104  of the created trace object that will represent
105  the IDI adapter.
106  Return 0 on error.
107 */
109  const diva_trace_library_user_interface_t *user_proc,
110  byte *pmem) {
112  int i;
113 
114  if (!pLib) {
115  return NULL;
116  }
117 
118  pmem += sizeof(*pLib);
119  memset(pLib, 0x00, sizeof(*pLib));
120 
121  pLib->Adapter = Adapter;
122 
123  /*
124  Set up Library Interface
125  */
126  pLib->instance.hLib = pLib;
127  pLib->instance.DivaSTraceLibraryStart = DivaSTraceLibraryStart;
128  pLib->instance.DivaSTraceLibraryStop = DivaSTraceLibraryStop;
129  pLib->instance.DivaSTraceLibraryFinit = SuperTraceLibraryFinit;
130  pLib->instance.DivaSTraceMessageInput = SuperTraceMessageInput;
131  pLib->instance.DivaSTraceGetHandle = SuperTraceGetHandle;
132  pLib->instance.DivaSTraceSetAudioTap = SuperTraceSetAudioTap;
133  pLib->instance.DivaSTraceSetBChannel = SuperTraceSetBChannel;
134  pLib->instance.DivaSTraceSetDChannel = SuperTraceSetDChannel;
135  pLib->instance.DivaSTraceSetInfo = SuperTraceSetInfo;
137  SuperTraceGetOutgoingCallStatistics;
139  SuperTraceGetIncomingCallStatistics;
141  SuperTraceGetModemStatistics;
143  SuperTraceGetFaxStatistics;
145  SuperTraceGetBLayer1Statistics;
147  SuperTraceGetBLayer2Statistics;
149  SuperTraceGetDLayer1Statistics;
151  SuperTraceGetDLayer2Statistics;
152  pLib->instance.DivaSTraceClearCall = SuperTraceClearCall;
153 
154 
155  if (user_proc) {
156  pLib->user_proc_table.user_context = user_proc->user_context;
157  pLib->user_proc_table.notify_proc = user_proc->notify_proc;
158  pLib->user_proc_table.trace_proc = user_proc->trace_proc;
160  }
161 
162  if (!(pLib->hAdapter = SuperTraceOpenAdapter(Adapter))) {
163  diva_mnt_internal_dprintf(0, DLI_ERR, "Can not open XDI adapter");
164  return NULL;
165  }
167 
168  /*
169  Calculate amount of parte table entites necessary to translate
170  information from all events of onterest
171  */
173  STAT_PARSE_ENTRIES + \
174  LINE_PARSE_ENTRIES + 1) * pLib->Channels;
175  pLib->parse_table = (diva_strace_path2action_t *)pmem;
176 
177  for (i = 0; i < 30; i++) {
178  pLib->lines[i].pInterface = &pLib->Interface;
179  pLib->lines[i].pInterfaceStat = &pLib->InterfaceStat;
180  }
181 
182  pLib->e.R = &pLib->RData;
183 
184  pLib->req_busy = 1;
185  pLib->rc_ok = ASSIGN_OK;
186 
187  diva_create_parse_table(pLib);
188 
189  return ((diva_strace_library_interface_t *)pLib);
190 }
191 
192 static int DivaSTraceLibraryStart(void *hLib) {
194 
195  return (SuperTraceASSIGN(pLib->hAdapter, pLib->buffer));
196 }
197 
198 /*
199  Return (-1) on error
200  Return (0) if was initiated or pending
201  Return (1) if removal is complete
202 */
203 static int DivaSTraceLibraryStop(void *hLib) {
205 
206  if (!pLib->e.Id) { /* Was never started/assigned */
207  return (1);
208  }
209 
210  switch (pLib->removal_state) {
211  case 0:
212  pLib->removal_state = 1;
213  ScheduleNextTraceRequest(pLib);
214  break;
215 
216  case 3:
217  return (1);
218  }
219 
220  return (0);
221 }
222 
223 static int SuperTraceLibraryFinit(void *hLib) {
225  if (pLib) {
226  if (pLib->hAdapter) {
228  }
229  return (0);
230  }
231  return (-1);
232 }
233 
234 static void *SuperTraceGetHandle(void *hLib) {
236 
237  return (&pLib->e);
238 }
239 
240 /*
241  After library handle object is gone in signaled state
242  this function should be called and will pick up incoming
243  IDI messages (return codes and indications).
244 */
245 static int SuperTraceMessageInput(void *hLib) {
247  int ret = 0;
248  byte Rc, Ind;
249 
250  if (pLib->e.complete == 255) {
251  /*
252  Process return code
253  */
254  pLib->req_busy = 0;
255  Rc = pLib->e.Rc;
256  pLib->e.Rc = 0;
257 
258  if (pLib->removal_state == 2) {
259  pLib->removal_state = 3;
260  return (0);
261  }
262 
263  if (Rc != pLib->rc_ok) {
264  int ignore = 0;
265  /*
266  Auto-detect amount of events/channels and features
267  */
268  if (pLib->general_b_ch_event == 1) {
269  pLib->general_b_ch_event = 2;
270  ignore = 1;
271  } else if (pLib->general_fax_event == 1) {
272  pLib->general_fax_event = 2;
273  ignore = 1;
274  } else if (pLib->general_mdm_event == 1) {
275  pLib->general_mdm_event = 2;
276  ignore = 1;
277  } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
278  pLib->ChannelsTraceActive = pLib->Channels;
279  ignore = 1;
280  } else if (pLib->ModemTraceActive < pLib->Channels) {
281  pLib->ModemTraceActive = pLib->Channels;
282  ignore = 1;
283  } else if (pLib->FaxTraceActive < pLib->Channels) {
284  pLib->FaxTraceActive = pLib->Channels;
285  ignore = 1;
286  } else if (pLib->audio_trace_init == 2) {
287  ignore = 1;
288  pLib->audio_trace_init = 1;
289  } else if (pLib->eye_pattern_pending) {
290  pLib->eye_pattern_pending = 0;
291  ignore = 1;
292  } else if (pLib->audio_tap_pending) {
293  pLib->audio_tap_pending = 0;
294  ignore = 1;
295  }
296 
297  if (!ignore) {
298  return (-1); /* request failed */
299  }
300  } else {
301  if (pLib->general_b_ch_event == 1) {
302  pLib->ChannelsTraceActive = pLib->Channels;
303  pLib->general_b_ch_event = 2;
304  } else if (pLib->general_fax_event == 1) {
305  pLib->general_fax_event = 2;
306  pLib->FaxTraceActive = pLib->Channels;
307  } else if (pLib->general_mdm_event == 1) {
308  pLib->general_mdm_event = 2;
309  pLib->ModemTraceActive = pLib->Channels;
310  }
311  }
312  if (pLib->audio_trace_init == 2) {
313  pLib->audio_trace_init = 1;
314  }
315  pLib->rc_ok = 0xff; /* default OK after assign was done */
316  if ((ret = ScheduleNextTraceRequest(pLib))) {
317  return (-1);
318  }
319  } else {
320  /*
321  Process indication
322  Always 'RNR' indication if return code is pending
323  */
324  Ind = pLib->e.Ind;
325  pLib->e.Ind = 0;
326  if (pLib->removal_state) {
327  pLib->e.RNum = 0;
328  pLib->e.RNR = 2;
329  } else if (pLib->req_busy) {
330  pLib->e.RNum = 0;
331  pLib->e.RNR = 1;
332  } else {
333  if (pLib->e.complete != 0x02) {
334  /*
335  Look-ahead call, set up buffers
336  */
337  pLib->e.RNum = 1;
338  pLib->e.R->P = (byte *)&pLib->buffer[0];
339  pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
340 
341  } else {
342  /*
343  Indication reception complete, process it now
344  */
345  byte *p = (byte *)&pLib->buffer[0];
346  pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
347 
348  switch (Ind) {
349  case MAN_COMBI_IND: {
350  int total_length = pLib->e.R->PLength;
351  word this_ind_length;
352 
353  while (total_length > 3 && *p) {
354  Ind = *p++;
355  this_ind_length = (word)p[0] | ((word)p[1] << 8);
356  p += 2;
357 
358  switch (Ind) {
359  case MAN_INFO_IND:
360  if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
361  return (-1);
362  }
363  break;
364  case MAN_EVENT_IND:
365  if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
366  return (-1);
367  }
368  break;
369  case MAN_TRACE_IND:
370  if (pLib->trace_on == 1) {
371  /*
372  Ignore first trace event that is result of
373  EVENT_ON operation
374  */
375  pLib->trace_on++;
376  } else {
377  /*
378  Delivery XLOG buffer to application
379  */
380  if (pLib->user_proc_table.trace_proc) {
382  &pLib->instance, pLib->Adapter,
383  p, this_ind_length);
384  }
385  }
386  break;
387  default:
388  diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
389  }
390  p += (this_ind_length + 1);
391  total_length -= (4 + this_ind_length);
392  }
393  } break;
394  case MAN_INFO_IND:
395  if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
396  return (-1);
397  }
398  break;
399  case MAN_EVENT_IND:
400  if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
401  return (-1);
402  }
403  break;
404  case MAN_TRACE_IND:
405  if (pLib->trace_on == 1) {
406  /*
407  Ignore first trace event that is result of
408  EVENT_ON operation
409  */
410  pLib->trace_on++;
411  } else {
412  /*
413  Delivery XLOG buffer to application
414  */
415  if (pLib->user_proc_table.trace_proc) {
417  &pLib->instance, pLib->Adapter,
418  p, pLib->e.R->PLength);
419  }
420  }
421  break;
422  default:
423  diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
424  }
425  }
426  }
427  }
428 
429  if ((ret = ScheduleNextTraceRequest(pLib))) {
430  return (-1);
431  }
432 
433  return (ret);
434 }
435 
436 /*
437  Internal state machine responsible for scheduling of requests
438 */
439 static int ScheduleNextTraceRequest(diva_strace_context_t *pLib) {
440  char name[64];
441  int ret = 0;
442  int i;
443 
444  if (pLib->req_busy) {
445  return (0);
446  }
447 
448  if (pLib->removal_state == 1) {
449  if (SuperTraceREMOVE(pLib->hAdapter)) {
450  pLib->removal_state = 3;
451  } else {
452  pLib->req_busy = 1;
453  pLib->removal_state = 2;
454  }
455  return (0);
456  }
457 
458  if (pLib->removal_state) {
459  return (0);
460  }
461 
462  if (!pLib->general_b_ch_event) {
463  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\B Event", pLib->buffer))) {
464  return (-1);
465  }
466  pLib->general_b_ch_event = 1;
467  pLib->req_busy = 1;
468  return (0);
469  }
470 
471  if (!pLib->general_fax_event) {
472  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\FAX Event", pLib->buffer))) {
473  return (-1);
474  }
475  pLib->general_fax_event = 1;
476  pLib->req_busy = 1;
477  return (0);
478  }
479 
480  if (!pLib->general_mdm_event) {
481  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\Modem Event", pLib->buffer))) {
482  return (-1);
483  }
484  pLib->general_mdm_event = 1;
485  pLib->req_busy = 1;
486  return (0);
487  }
488 
489  if (pLib->ChannelsTraceActive < pLib->Channels) {
490  pLib->ChannelsTraceActive++;
491  sprintf(name, "State\\B%d\\Line", pLib->ChannelsTraceActive);
492  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
493  pLib->ChannelsTraceActive--;
494  return (-1);
495  }
496  pLib->req_busy = 1;
497  return (0);
498  }
499 
500  if (pLib->ModemTraceActive < pLib->Channels) {
501  pLib->ModemTraceActive++;
502  sprintf(name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive);
503  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
504  pLib->ModemTraceActive--;
505  return (-1);
506  }
507  pLib->req_busy = 1;
508  return (0);
509  }
510 
511  if (pLib->FaxTraceActive < pLib->Channels) {
512  pLib->FaxTraceActive++;
513  sprintf(name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive);
514  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
515  pLib->FaxTraceActive--;
516  return (-1);
517  }
518  pLib->req_busy = 1;
519  return (0);
520  }
521 
522  if (!pLib->trace_mask_init) {
523  word tmp = 0x0000;
524  if (SuperTraceWriteVar(pLib->hAdapter,
525  pLib->buffer,
526  "Trace\\Event Enable",
527  &tmp,
528  0x87, /* MI_BITFLD */
529  sizeof(tmp))) {
530  return (-1);
531  }
532  pLib->trace_mask_init = 1;
533  pLib->req_busy = 1;
534  return (0);
535  }
536 
537  if (!pLib->audio_trace_init) {
538  dword tmp = 0x00000000;
539  if (SuperTraceWriteVar(pLib->hAdapter,
540  pLib->buffer,
541  "Trace\\AudioCh# Enable",
542  &tmp,
543  0x87, /* MI_BITFLD */
544  sizeof(tmp))) {
545  return (-1);
546  }
547  pLib->audio_trace_init = 2;
548  pLib->req_busy = 1;
549  return (0);
550  }
551 
552  if (!pLib->bchannel_init) {
553  dword tmp = 0x00000000;
554  if (SuperTraceWriteVar(pLib->hAdapter,
555  pLib->buffer,
556  "Trace\\B-Ch# Enable",
557  &tmp,
558  0x87, /* MI_BITFLD */
559  sizeof(tmp))) {
560  return (-1);
561  }
562  pLib->bchannel_init = 1;
563  pLib->req_busy = 1;
564  return (0);
565  }
566 
567  if (!pLib->trace_length_init) {
568  word tmp = 30;
569  if (SuperTraceWriteVar(pLib->hAdapter,
570  pLib->buffer,
571  "Trace\\Max Log Length",
572  &tmp,
573  0x82, /* MI_UINT */
574  sizeof(tmp))) {
575  return (-1);
576  }
577  pLib->trace_length_init = 1;
578  pLib->req_busy = 1;
579  return (0);
580  }
581 
582  if (!pLib->trace_on) {
584  "Trace\\Log Buffer",
585  pLib->buffer)) {
586  return (-1);
587  }
588  pLib->trace_on = 1;
589  pLib->req_busy = 1;
590  return (0);
591  }
592 
593  if (pLib->trace_event_mask != pLib->current_trace_event_mask) {
594  if (SuperTraceWriteVar(pLib->hAdapter,
595  pLib->buffer,
596  "Trace\\Event Enable",
597  &pLib->trace_event_mask,
598  0x87, /* MI_BITFLD */
599  sizeof(pLib->trace_event_mask))) {
600  return (-1);
601  }
603  pLib->req_busy = 1;
604  return (0);
605  }
606 
607  if ((pLib->audio_tap_pending >= 0) && (pLib->audio_tap_mask != pLib->current_audio_tap_mask)) {
608  if (SuperTraceWriteVar(pLib->hAdapter,
609  pLib->buffer,
610  "Trace\\AudioCh# Enable",
611  &pLib->audio_tap_mask,
612  0x87, /* MI_BITFLD */
613  sizeof(pLib->audio_tap_mask))) {
614  return (-1);
615  }
617  pLib->audio_tap_pending = 1;
618  pLib->req_busy = 1;
619  return (0);
620  }
621 
622  if ((pLib->eye_pattern_pending >= 0) && (pLib->audio_tap_mask != pLib->current_eye_pattern_mask)) {
623  if (SuperTraceWriteVar(pLib->hAdapter,
624  pLib->buffer,
625  "Trace\\EyeCh# Enable",
626  &pLib->audio_tap_mask,
627  0x87, /* MI_BITFLD */
628  sizeof(pLib->audio_tap_mask))) {
629  return (-1);
630  }
632  pLib->eye_pattern_pending = 1;
633  pLib->req_busy = 1;
634  return (0);
635  }
636 
638  if (SuperTraceWriteVar(pLib->hAdapter,
639  pLib->buffer,
640  "Trace\\B-Ch# Enable",
641  &pLib->bchannel_trace_mask,
642  0x87, /* MI_BITFLD */
643  sizeof(pLib->bchannel_trace_mask))) {
644  return (-1);
645  }
647  pLib->req_busy = 1;
648  return (0);
649  }
650 
651  if (!pLib->trace_events_down) {
653  "Events Down",
654  pLib->buffer)) {
655  return (-1);
656  }
657  pLib->trace_events_down = 1;
658  pLib->req_busy = 1;
659  return (0);
660  }
661 
662  if (!pLib->l1_trace) {
664  "State\\Layer1",
665  pLib->buffer)) {
666  return (-1);
667  }
668  pLib->l1_trace = 1;
669  pLib->req_busy = 1;
670  return (0);
671  }
672 
673  if (!pLib->l2_trace) {
675  "State\\Layer2 No1",
676  pLib->buffer)) {
677  return (-1);
678  }
679  pLib->l2_trace = 1;
680  pLib->req_busy = 1;
681  return (0);
682  }
683 
684  for (i = 0; i < 30; i++) {
685  if (pLib->pending_line_status & (1L << i)) {
686  sprintf(name, "State\\B%d", i + 1);
687  if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
688  return (-1);
689  }
690  pLib->pending_line_status &= ~(1L << i);
691  pLib->req_busy = 1;
692  return (0);
693  }
694  if (pLib->pending_modem_status & (1L << i)) {
695  sprintf(name, "State\\B%d\\Modem", i + 1);
696  if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
697  return (-1);
698  }
699  pLib->pending_modem_status &= ~(1L << i);
700  pLib->req_busy = 1;
701  return (0);
702  }
703  if (pLib->pending_fax_status & (1L << i)) {
704  sprintf(name, "State\\B%d\\FAX", i + 1);
705  if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
706  return (-1);
707  }
708  pLib->pending_fax_status &= ~(1L << i);
709  pLib->req_busy = 1;
710  return (0);
711  }
712  if (pLib->clear_call_command & (1L << i)) {
713  sprintf(name, "State\\B%d\\Clear Call", i + 1);
714  if (SuperTraceExecuteRequest(pLib->hAdapter, name, pLib->buffer)) {
715  return (-1);
716  }
717  pLib->clear_call_command &= ~(1L << i);
718  pLib->req_busy = 1;
719  return (0);
720  }
721  }
722 
723  if (pLib->outgoing_ifc_stats) {
725  "Statistics\\Outgoing Calls",
726  pLib->buffer)) {
727  return (-1);
728  }
729  pLib->outgoing_ifc_stats = 0;
730  pLib->req_busy = 1;
731  return (0);
732  }
733 
734  if (pLib->incoming_ifc_stats) {
736  "Statistics\\Incoming Calls",
737  pLib->buffer)) {
738  return (-1);
739  }
740  pLib->incoming_ifc_stats = 0;
741  pLib->req_busy = 1;
742  return (0);
743  }
744 
745  if (pLib->modem_ifc_stats) {
747  "Statistics\\Modem",
748  pLib->buffer)) {
749  return (-1);
750  }
751  pLib->modem_ifc_stats = 0;
752  pLib->req_busy = 1;
753  return (0);
754  }
755 
756  if (pLib->fax_ifc_stats) {
758  "Statistics\\FAX",
759  pLib->buffer)) {
760  return (-1);
761  }
762  pLib->fax_ifc_stats = 0;
763  pLib->req_busy = 1;
764  return (0);
765  }
766 
767  if (pLib->b1_ifc_stats) {
769  "Statistics\\B-Layer1",
770  pLib->buffer)) {
771  return (-1);
772  }
773  pLib->b1_ifc_stats = 0;
774  pLib->req_busy = 1;
775  return (0);
776  }
777 
778  if (pLib->b2_ifc_stats) {
780  "Statistics\\B-Layer2",
781  pLib->buffer)) {
782  return (-1);
783  }
784  pLib->b2_ifc_stats = 0;
785  pLib->req_busy = 1;
786  return (0);
787  }
788 
789  if (pLib->d1_ifc_stats) {
791  "Statistics\\D-Layer1",
792  pLib->buffer)) {
793  return (-1);
794  }
795  pLib->d1_ifc_stats = 0;
796  pLib->req_busy = 1;
797  return (0);
798  }
799 
800  if (pLib->d2_ifc_stats) {
802  "Statistics\\D-Layer2",
803  pLib->buffer)) {
804  return (-1);
805  }
806  pLib->d2_ifc_stats = 0;
807  pLib->req_busy = 1;
808  return (0);
809  }
810 
811  if (!pLib->IncomingCallsCallsActive) {
812  pLib->IncomingCallsCallsActive = 1;
813  sprintf(name, "%s", "Statistics\\Incoming Calls\\Calls");
814  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
815  pLib->IncomingCallsCallsActive = 0;
816  return (-1);
817  }
818  pLib->req_busy = 1;
819  return (0);
820  }
821  if (!pLib->IncomingCallsConnectedActive) {
823  sprintf(name, "%s", "Statistics\\Incoming Calls\\Connected");
824  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
826  return (-1);
827  }
828  pLib->req_busy = 1;
829  return (0);
830  }
831  if (!pLib->OutgoingCallsCallsActive) {
832  pLib->OutgoingCallsCallsActive = 1;
833  sprintf(name, "%s", "Statistics\\Outgoing Calls\\Calls");
834  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
835  pLib->OutgoingCallsCallsActive = 0;
836  return (-1);
837  }
838  pLib->req_busy = 1;
839  return (0);
840  }
841  if (!pLib->OutgoingCallsConnectedActive) {
843  sprintf(name, "%s", "Statistics\\Outgoing Calls\\Connected");
844  if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
846  return (-1);
847  }
848  pLib->req_busy = 1;
849  return (0);
850  }
851 
852  return (0);
853 }
854 
855 static int process_idi_event(diva_strace_context_t *pLib,
856  diva_man_var_header_t *pVar) {
857  const char *path = (char *)&pVar->path_length + 1;
858  char name[64];
859  int i;
860 
861  if (!strncmp("State\\B Event", path, pVar->path_length)) {
862  dword ch_id;
863  if (!diva_trace_read_variable(pVar, &ch_id)) {
864  if (!pLib->line_init_event && !pLib->pending_line_status) {
865  for (i = 1; i <= pLib->Channels; i++) {
866  diva_line_event(pLib, i);
867  }
868  return (0);
869  } else if (ch_id && ch_id <= pLib->Channels) {
870  return (diva_line_event(pLib, (int)ch_id));
871  }
872  return (0);
873  }
874  return (-1);
875  }
876 
877  if (!strncmp("State\\FAX Event", path, pVar->path_length)) {
878  dword ch_id;
879  if (!diva_trace_read_variable(pVar, &ch_id)) {
880  if (!pLib->pending_fax_status && !pLib->fax_init_event) {
881  for (i = 1; i <= pLib->Channels; i++) {
882  diva_fax_event(pLib, i);
883  }
884  return (0);
885  } else if (ch_id && ch_id <= pLib->Channels) {
886  return (diva_fax_event(pLib, (int)ch_id));
887  }
888  return (0);
889  }
890  return (-1);
891  }
892 
893  if (!strncmp("State\\Modem Event", path, pVar->path_length)) {
894  dword ch_id;
895  if (!diva_trace_read_variable(pVar, &ch_id)) {
896  if (!pLib->pending_modem_status && !pLib->modem_init_event) {
897  for (i = 1; i <= pLib->Channels; i++) {
898  diva_modem_event(pLib, i);
899  }
900  return (0);
901  } else if (ch_id && ch_id <= pLib->Channels) {
902  return (diva_modem_event(pLib, (int)ch_id));
903  }
904  return (0);
905  }
906  return (-1);
907  }
908 
909  /*
910  First look for Line Event
911  */
912  for (i = 1; i <= pLib->Channels; i++) {
913  sprintf(name, "State\\B%d\\Line", i);
914  if (find_var(pVar, name)) {
915  return (diva_line_event(pLib, i));
916  }
917  }
918 
919  /*
920  Look for Moden Progress Event
921  */
922  for (i = 1; i <= pLib->Channels; i++) {
923  sprintf(name, "State\\B%d\\Modem\\Event", i);
924  if (find_var(pVar, name)) {
925  return (diva_modem_event(pLib, i));
926  }
927  }
928 
929  /*
930  Look for Fax Event
931  */
932  for (i = 1; i <= pLib->Channels; i++) {
933  sprintf(name, "State\\B%d\\FAX\\Event", i);
934  if (find_var(pVar, name)) {
935  return (diva_fax_event(pLib, i));
936  }
937  }
938 
939  /*
940  Notification about loss of events
941  */
942  if (!strncmp("Events Down", path, pVar->path_length)) {
943  if (pLib->trace_events_down == 1) {
944  pLib->trace_events_down = 2;
945  } else {
946  diva_trace_error(pLib, 1, "Events Down", 0);
947  }
948  return (0);
949  }
950 
951  if (!strncmp("State\\Layer1", path, pVar->path_length)) {
952  diva_strace_read_asz(pVar, &pLib->lines[0].pInterface->Layer1[0]);
953  if (pLib->l1_trace == 1) {
954  pLib->l1_trace = 2;
955  } else {
956  diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
957  }
958  return (0);
959  }
960  if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
961  char *tmp = &pLib->lines[0].pInterface->Layer2[0];
962  dword l2_state;
963  if (diva_strace_read_uint(pVar, &l2_state))
964  return -1;
965 
966  switch (l2_state) {
967  case 0:
968  strcpy(tmp, "Idle");
969  break;
970  case 1:
971  strcpy(tmp, "Layer2 UP");
972  break;
973  case 2:
974  strcpy(tmp, "Layer2 Disconnecting");
975  break;
976  case 3:
977  strcpy(tmp, "Layer2 Connecting");
978  break;
979  case 4:
980  strcpy(tmp, "SPID Initializing");
981  break;
982  case 5:
983  strcpy(tmp, "SPID Initialised");
984  break;
985  case 6:
986  strcpy(tmp, "Layer2 Connecting");
987  break;
988 
989  case 7:
990  strcpy(tmp, "Auto SPID Stopped");
991  break;
992 
993  case 8:
994  strcpy(tmp, "Auto SPID Idle");
995  break;
996 
997  case 9:
998  strcpy(tmp, "Auto SPID Requested");
999  break;
1000 
1001  case 10:
1002  strcpy(tmp, "Auto SPID Delivery");
1003  break;
1004 
1005  case 11:
1006  strcpy(tmp, "Auto SPID Complete");
1007  break;
1008 
1009  default:
1010  sprintf(tmp, "U:%d", (int)l2_state);
1011  }
1012  if (pLib->l2_trace == 1) {
1013  pLib->l2_trace = 2;
1014  } else {
1015  diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
1016  }
1017  return (0);
1018  }
1019 
1020  if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) ||
1021  !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
1022  return (SuperTraceGetIncomingCallStatistics(pLib));
1023  }
1024 
1025  if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) ||
1026  !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
1027  return (SuperTraceGetOutgoingCallStatistics(pLib));
1028  }
1029 
1030  return (-1);
1031 }
1032 
1033 static int diva_line_event(diva_strace_context_t *pLib, int Channel) {
1034  pLib->pending_line_status |= (1L << (Channel - 1));
1035  return (0);
1036 }
1037 
1038 static int diva_modem_event(diva_strace_context_t *pLib, int Channel) {
1039  pLib->pending_modem_status |= (1L << (Channel - 1));
1040  return (0);
1041 }
1042 
1043 static int diva_fax_event(diva_strace_context_t *pLib, int Channel) {
1044  pLib->pending_fax_status |= (1L << (Channel - 1));
1045  return (0);
1046 }
1047 
1048 /*
1049  Process INFO indications that arrive from the card
1050  Uses path of first I.E. to detect the source of the
1051  infication
1052 */
1053 static int process_idi_info(diva_strace_context_t *pLib,
1054  diva_man_var_header_t *pVar) {
1055  const char *path = (char *)&pVar->path_length + 1;
1056  char name[64];
1057  int i, len;
1058 
1059  /*
1060  First look for Modem Status Info
1061  */
1062  for (i = pLib->Channels; i > 0; i--) {
1063  len = sprintf(name, "State\\B%d\\Modem", i);
1064  if (!strncmp(name, path, len)) {
1065  return (diva_modem_info(pLib, i, pVar));
1066  }
1067  }
1068 
1069  /*
1070  Look for Fax Status Info
1071  */
1072  for (i = pLib->Channels; i > 0; i--) {
1073  len = sprintf(name, "State\\B%d\\FAX", i);
1074  if (!strncmp(name, path, len)) {
1075  return (diva_fax_info(pLib, i, pVar));
1076  }
1077  }
1078 
1079  /*
1080  Look for Line Status Info
1081  */
1082  for (i = pLib->Channels; i > 0; i--) {
1083  len = sprintf(name, "State\\B%d", i);
1084  if (!strncmp(name, path, len)) {
1085  return (diva_line_info(pLib, i, pVar));
1086  }
1087  }
1088 
1089  if (!diva_ifc_statistics(pLib, pVar)) {
1090  return (0);
1091  }
1092 
1093  return (-1);
1094 }
1095 
1096 /*
1097  MODEM INSTANCE STATE UPDATE
1098 
1099  Update Modem Status Information and issue notification to user,
1100  that will inform about change in the state of modem instance, that is
1101  associuated with this channel
1102 */
1103 static int diva_modem_info(diva_strace_context_t *pLib,
1104  int Channel,
1105  diva_man_var_header_t *pVar) {
1107  int i, nr = Channel - 1;
1108 
1109  for (i = pLib->modem_parse_entry_first[nr];
1110  i <= pLib->modem_parse_entry_last[nr]; i++) {
1111  if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1112  if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1113  diva_trace_error(pLib, -3, __FILE__, __LINE__);
1114  return (-1);
1115  }
1116  } else {
1117  diva_trace_error(pLib, -2, __FILE__, __LINE__);
1118  return (-1);
1119  }
1120  }
1121 
1122  /*
1123  We do not use first event to notify user - this is the event that is
1124  generated as result of EVENT ON operation and is used only to initialize
1125  internal variables of application
1126  */
1127  if (pLib->modem_init_event & (1L << nr)) {
1128  diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
1129  } else {
1130  pLib->modem_init_event |= (1L << nr);
1131  }
1132 
1133  return (0);
1134 }
1135 
1136 static int diva_fax_info(diva_strace_context_t *pLib,
1137  int Channel,
1138  diva_man_var_header_t *pVar) {
1140  int i, nr = Channel - 1;
1141 
1142  for (i = pLib->fax_parse_entry_first[nr];
1143  i <= pLib->fax_parse_entry_last[nr]; i++) {
1144  if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1145  if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1146  diva_trace_error(pLib, -3, __FILE__, __LINE__);
1147  return (-1);
1148  }
1149  } else {
1150  diva_trace_error(pLib, -2, __FILE__, __LINE__);
1151  return (-1);
1152  }
1153  }
1154 
1155  /*
1156  We do not use first event to notify user - this is the event that is
1157  generated as result of EVENT ON operation and is used only to initialize
1158  internal variables of application
1159  */
1160  if (pLib->fax_init_event & (1L << nr)) {
1161  diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
1162  } else {
1163  pLib->fax_init_event |= (1L << nr);
1164  }
1165 
1166  return (0);
1167 }
1168 
1169 /*
1170  LINE STATE UPDATE
1171  Update Line Status Information and issue notification to user,
1172  that will inform about change in the line state.
1173 */
1174 static int diva_line_info(diva_strace_context_t *pLib,
1175  int Channel,
1176  diva_man_var_header_t *pVar) {
1178  int i, nr = Channel - 1;
1179 
1180  for (i = pLib->line_parse_entry_first[nr];
1181  i <= pLib->line_parse_entry_last[nr]; i++) {
1182  if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
1183  if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
1184  diva_trace_error(pLib, -3, __FILE__, __LINE__);
1185  return (-1);
1186  }
1187  } else {
1188  diva_trace_error(pLib, -2 , __FILE__, __LINE__);
1189  return (-1);
1190  }
1191  }
1192 
1193  /*
1194  We do not use first event to notify user - this is the event that is
1195  generated as result of EVENT ON operation and is used only to initialize
1196  internal variables of application
1197 
1198  Exception is is if the line is "online". In this case we have to notify
1199  user about this confition.
1200  */
1201  if (pLib->line_init_event & (1L << nr)) {
1202  diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1203  } else {
1204  pLib->line_init_event |= (1L << nr);
1205  if (strcmp(&pLib->lines[nr].Line[0], "Idle")) {
1206  diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
1207  }
1208  }
1209 
1210  return (0);
1211 }
1212 
1213 /*
1214  Move position to next vatianle in the chain
1215 */
1216 static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar) {
1217  byte *msg = (byte *)pVar;
1218  byte *start;
1219  int msg_length;
1220 
1221  if (*msg != ESC) return NULL;
1222 
1223  start = msg + 2;
1224  msg_length = *(msg + 1);
1225  msg = (start + msg_length);
1226 
1227  if (*msg != ESC) return NULL;
1228 
1229  return ((diva_man_var_header_t *)msg);
1230 }
1231 
1232 /*
1233  Move position to variable with given name
1234 */
1235 static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
1236  const char *name) {
1237  const char *path;
1238 
1239  do {
1240  path = (char *)&pVar->path_length + 1;
1241 
1242  if (!strncmp(name, path, pVar->path_length)) {
1243  break;
1244  }
1245  } while ((pVar = get_next_var(pVar)));
1246 
1247  return (pVar);
1248 }
1249 
1250 static void diva_create_line_parse_table(diva_strace_context_t *pLib,
1251  int Channel) {
1252  diva_trace_line_state_t *pLine = &pLib->lines[Channel];
1253  int nr = Channel + 1;
1254 
1255  if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) {
1256  diva_trace_error(pLib, -1, __FILE__, __LINE__);
1257  return;
1258  }
1259 
1260  pLine->ChannelNumber = nr;
1261 
1263 
1264  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1265  "State\\B%d\\Framing", nr);
1266  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0];
1267 
1268  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1269  "State\\B%d\\Line", nr);
1270  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0];
1271 
1272  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1273  "State\\B%d\\Layer2", nr);
1274  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0];
1275 
1276  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1277  "State\\B%d\\Layer3", nr);
1278  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0];
1279 
1280  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1281  "State\\B%d\\Remote Address", nr);
1282  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1283  &pLine->RemoteAddress[0];
1284 
1285  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1286  "State\\B%d\\Remote SubAddr", nr);
1287  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1288  &pLine->RemoteSubAddress[0];
1289 
1290  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1291  "State\\B%d\\Local Address", nr);
1292  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1293  &pLine->LocalAddress[0];
1294 
1295  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1296  "State\\B%d\\Local SubAddr", nr);
1297  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1298  &pLine->LocalSubAddress[0];
1299 
1300  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1301  "State\\B%d\\BC", nr);
1302  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC;
1303 
1304  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1305  "State\\B%d\\HLC", nr);
1306  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC;
1307 
1308  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1309  "State\\B%d\\LLC", nr);
1310  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC;
1311 
1312  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1313  "State\\B%d\\Charges", nr);
1314  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges;
1315 
1316  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1317  "State\\B%d\\Call Reference", nr);
1318  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference;
1319 
1320  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1321  "State\\B%d\\Last Disc Cause", nr);
1322  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1323  &pLine->LastDisconnecCause;
1324 
1325  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1326  "State\\B%d\\User ID", nr);
1327  pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0];
1328 
1329  pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1330 }
1331 
1332 static void diva_create_fax_parse_table(diva_strace_context_t *pLib,
1333  int Channel) {
1334  diva_trace_fax_state_t *pFax = &pLib->lines[Channel].fax;
1335  int nr = Channel + 1;
1336 
1337  if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) {
1338  diva_trace_error(pLib, -1, __FILE__, __LINE__);
1339  return;
1340  }
1341  pFax->ChannelNumber = nr;
1342 
1344 
1345  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1346  "State\\B%d\\FAX\\Event", nr);
1347  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event;
1348 
1349  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1350  "State\\B%d\\FAX\\Page Counter", nr);
1351  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter;
1352 
1353  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1354  "State\\B%d\\FAX\\Features", nr);
1355  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features;
1356 
1357  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1358  "State\\B%d\\FAX\\Station ID", nr);
1359  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0];
1360 
1361  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1362  "State\\B%d\\FAX\\Subaddress", nr);
1363  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0];
1364 
1365  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1366  "State\\B%d\\FAX\\Password", nr);
1367  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0];
1368 
1369  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1370  "State\\B%d\\FAX\\Speed", nr);
1371  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed;
1372 
1373  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1374  "State\\B%d\\FAX\\Resolution", nr);
1375  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution;
1376 
1377  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1378  "State\\B%d\\FAX\\Paper Width", nr);
1379  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width;
1380 
1381  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1382  "State\\B%d\\FAX\\Paper Length", nr);
1383  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length;
1384 
1385  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1386  "State\\B%d\\FAX\\Scanline Time", nr);
1387  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time;
1388 
1389  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1390  "State\\B%d\\FAX\\Disc Reason", nr);
1391  pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason;
1392 
1393  pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1394 }
1395 
1396 static void diva_create_modem_parse_table(diva_strace_context_t *pLib,
1397  int Channel) {
1398  diva_trace_modem_state_t *pModem = &pLib->lines[Channel].modem;
1399  int nr = Channel + 1;
1400 
1401  if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) {
1402  diva_trace_error(pLib, -1, __FILE__, __LINE__);
1403  return;
1404  }
1405  pModem->ChannelNumber = nr;
1406 
1408 
1409  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1410  "State\\B%d\\Modem\\Event", nr);
1411  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event;
1412 
1413  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1414  "State\\B%d\\Modem\\Norm", nr);
1415  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm;
1416 
1417  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1418  "State\\B%d\\Modem\\Options", nr);
1419  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options;
1420 
1421  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1422  "State\\B%d\\Modem\\TX Speed", nr);
1423  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed;
1424 
1425  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1426  "State\\B%d\\Modem\\RX Speed", nr);
1427  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed;
1428 
1429  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1430  "State\\B%d\\Modem\\Roundtrip ms", nr);
1431  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec;
1432 
1433  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1434  "State\\B%d\\Modem\\Symbol Rate", nr);
1435  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate;
1436 
1437  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1438  "State\\B%d\\Modem\\RX Level dBm", nr);
1439  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm;
1440 
1441  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1442  "State\\B%d\\Modem\\Echo Level dBm", nr);
1443  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm;
1444 
1445  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1446  "State\\B%d\\Modem\\SNR dB", nr);
1447  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb;
1448 
1449  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1450  "State\\B%d\\Modem\\MAE", nr);
1451  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE;
1452 
1453  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1454  "State\\B%d\\Modem\\Local Retrains", nr);
1455  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains;
1456 
1457  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1458  "State\\B%d\\Modem\\Remote Retrains", nr);
1459  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains;
1460 
1461  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1462  "State\\B%d\\Modem\\Local Resyncs", nr);
1463  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs;
1464 
1465  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1466  "State\\B%d\\Modem\\Remote Resyncs", nr);
1467  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs;
1468 
1469  sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
1470  "State\\B%d\\Modem\\Disc Reason", nr);
1471  pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason;
1472 
1473  pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
1474 }
1475 
1476 static void diva_create_parse_table(diva_strace_context_t *pLib) {
1477  int i;
1478 
1479  for (i = 0; i < pLib->Channels; i++) {
1480  diva_create_line_parse_table(pLib, i);
1481  diva_create_modem_parse_table(pLib, i);
1482  diva_create_fax_parse_table(pLib, i);
1483  }
1484 
1485  pLib->statistic_parse_first = pLib->cur_parse_entry;
1486 
1487  /*
1488  Outgoing Calls
1489  */
1490  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1491  "Statistics\\Outgoing Calls\\Calls");
1492  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1493  &pLib->InterfaceStat.outg.Calls;
1494 
1495  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1496  "Statistics\\Outgoing Calls\\Connected");
1497  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1498  &pLib->InterfaceStat.outg.Connected;
1499 
1500  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1501  "Statistics\\Outgoing Calls\\User Busy");
1502  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1503  &pLib->InterfaceStat.outg.User_Busy;
1504 
1505  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1506  "Statistics\\Outgoing Calls\\No Answer");
1507  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1508  &pLib->InterfaceStat.outg.No_Answer;
1509 
1510  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1511  "Statistics\\Outgoing Calls\\Wrong Number");
1512  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1514 
1515  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1516  "Statistics\\Outgoing Calls\\Call Rejected");
1517  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1519 
1520  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1521  "Statistics\\Outgoing Calls\\Other Failures");
1522  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1524 
1525  /*
1526  Incoming Calls
1527  */
1528  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1529  "Statistics\\Incoming Calls\\Calls");
1530  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1531  &pLib->InterfaceStat.inc.Calls;
1532 
1533  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1534  "Statistics\\Incoming Calls\\Connected");
1535  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1536  &pLib->InterfaceStat.inc.Connected;
1537 
1538  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1539  "Statistics\\Incoming Calls\\User Busy");
1540  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1541  &pLib->InterfaceStat.inc.User_Busy;
1542 
1543  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1544  "Statistics\\Incoming Calls\\Call Rejected");
1545  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1547 
1548  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1549  "Statistics\\Incoming Calls\\Wrong Number");
1550  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1552 
1553  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1554  "Statistics\\Incoming Calls\\Incompatible Dst");
1555  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1557 
1558  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1559  "Statistics\\Incoming Calls\\Out of Order");
1560  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1562 
1563  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1564  "Statistics\\Incoming Calls\\Ignored");
1565  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1566  &pLib->InterfaceStat.inc.Ignored;
1567 
1568  /*
1569  Modem Statistics
1570  */
1572 
1573  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1574  "Statistics\\Modem\\Disc Normal");
1575  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1576  &pLib->InterfaceStat.mdm.Disc_Normal;
1577 
1578  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1579  "Statistics\\Modem\\Disc Unspecified");
1580  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1582 
1583  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1584  "Statistics\\Modem\\Disc Busy Tone");
1585  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1587 
1588  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1589  "Statistics\\Modem\\Disc Congestion");
1590  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1592 
1593  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1594  "Statistics\\Modem\\Disc Carr. Wait");
1595  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1597 
1598  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1599  "Statistics\\Modem\\Disc Trn Timeout");
1600  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1602 
1603  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1604  "Statistics\\Modem\\Disc Incompat.");
1605  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1607 
1608  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1609  "Statistics\\Modem\\Disc Frame Rej.");
1610  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1612 
1613  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1614  "Statistics\\Modem\\Disc V42bis");
1615  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1616  &pLib->InterfaceStat.mdm.Disc_V42bis;
1617 
1618  pLib->mdm_statistic_parse_last = pLib->cur_parse_entry - 1;
1619 
1620  /*
1621  Fax Statistics
1622  */
1624 
1625  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1626  "Statistics\\FAX\\Disc Normal");
1627  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1628  &pLib->InterfaceStat.fax.Disc_Normal;
1629 
1630  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1631  "Statistics\\FAX\\Disc Not Ident.");
1632  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1634 
1635  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1636  "Statistics\\FAX\\Disc No Response");
1637  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1639 
1640  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1641  "Statistics\\FAX\\Disc Retries");
1642  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1644 
1645  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1646  "Statistics\\FAX\\Disc Unexp. Msg.");
1647  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1649 
1650  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1651  "Statistics\\FAX\\Disc No Polling.");
1652  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1654 
1655  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1656  "Statistics\\FAX\\Disc Training");
1657  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1659 
1660  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1661  "Statistics\\FAX\\Disc Unexpected");
1662  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1664 
1665  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1666  "Statistics\\FAX\\Disc Application");
1667  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1669 
1670  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1671  "Statistics\\FAX\\Disc Incompat.");
1672  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1674 
1675  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1676  "Statistics\\FAX\\Disc No Command");
1677  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1679 
1680  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1681  "Statistics\\FAX\\Disc Long Msg");
1682  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1684 
1685  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1686  "Statistics\\FAX\\Disc Supervisor");
1687  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1689 
1690  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1691  "Statistics\\FAX\\Disc SUB SEP PWD");
1692  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1694 
1695  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1696  "Statistics\\FAX\\Disc Invalid Msg");
1697  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1699 
1700  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1701  "Statistics\\FAX\\Disc Page Coding");
1702  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1704 
1705  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1706  "Statistics\\FAX\\Disc App Timeout");
1707  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1709 
1710  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1711  "Statistics\\FAX\\Disc Unspecified");
1712  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1714 
1715  pLib->fax_statistic_parse_last = pLib->cur_parse_entry - 1;
1716 
1717  /*
1718  B-Layer1"
1719  */
1720  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1721  "Statistics\\B-Layer1\\X-Frames");
1722  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1723  &pLib->InterfaceStat.b1.X_Frames;
1724 
1725  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1726  "Statistics\\B-Layer1\\X-Bytes");
1727  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1728  &pLib->InterfaceStat.b1.X_Bytes;
1729 
1730  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1731  "Statistics\\B-Layer1\\X-Errors");
1732  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1733  &pLib->InterfaceStat.b1.X_Errors;
1734 
1735  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1736  "Statistics\\B-Layer1\\R-Frames");
1737  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1738  &pLib->InterfaceStat.b1.R_Frames;
1739 
1740  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1741  "Statistics\\B-Layer1\\R-Bytes");
1742  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1743  &pLib->InterfaceStat.b1.R_Bytes;
1744 
1745  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1746  "Statistics\\B-Layer1\\R-Errors");
1747  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1748  &pLib->InterfaceStat.b1.R_Errors;
1749 
1750  /*
1751  B-Layer2
1752  */
1753  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1754  "Statistics\\B-Layer2\\X-Frames");
1755  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1756  &pLib->InterfaceStat.b2.X_Frames;
1757 
1758  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1759  "Statistics\\B-Layer2\\X-Bytes");
1760  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1761  &pLib->InterfaceStat.b2.X_Bytes;
1762 
1763  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1764  "Statistics\\B-Layer2\\X-Errors");
1765  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1766  &pLib->InterfaceStat.b2.X_Errors;
1767 
1768  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1769  "Statistics\\B-Layer2\\R-Frames");
1770  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1771  &pLib->InterfaceStat.b2.R_Frames;
1772 
1773  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1774  "Statistics\\B-Layer2\\R-Bytes");
1775  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1776  &pLib->InterfaceStat.b2.R_Bytes;
1777 
1778  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1779  "Statistics\\B-Layer2\\R-Errors");
1780  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1781  &pLib->InterfaceStat.b2.R_Errors;
1782 
1783  /*
1784  D-Layer1
1785  */
1786  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1787  "Statistics\\D-Layer1\\X-Frames");
1788  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1789  &pLib->InterfaceStat.d1.X_Frames;
1790 
1791  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1792  "Statistics\\D-Layer1\\X-Bytes");
1793  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1794  &pLib->InterfaceStat.d1.X_Bytes;
1795 
1796  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1797  "Statistics\\D-Layer1\\X-Errors");
1798  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1799  &pLib->InterfaceStat.d1.X_Errors;
1800 
1801  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1802  "Statistics\\D-Layer1\\R-Frames");
1803  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1804  &pLib->InterfaceStat.d1.R_Frames;
1805 
1806  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1807  "Statistics\\D-Layer1\\R-Bytes");
1808  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1809  &pLib->InterfaceStat.d1.R_Bytes;
1810 
1811  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1812  "Statistics\\D-Layer1\\R-Errors");
1813  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1814  &pLib->InterfaceStat.d1.R_Errors;
1815 
1816  /*
1817  D-Layer2
1818  */
1819  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1820  "Statistics\\D-Layer2\\X-Frames");
1821  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1822  &pLib->InterfaceStat.d2.X_Frames;
1823 
1824  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1825  "Statistics\\D-Layer2\\X-Bytes");
1826  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1827  &pLib->InterfaceStat.d2.X_Bytes;
1828 
1829  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1830  "Statistics\\D-Layer2\\X-Errors");
1831  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1832  &pLib->InterfaceStat.d2.X_Errors;
1833 
1834  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1835  "Statistics\\D-Layer2\\R-Frames");
1836  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1837  &pLib->InterfaceStat.d2.R_Frames;
1838 
1839  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1840  "Statistics\\D-Layer2\\R-Bytes");
1841  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1842  &pLib->InterfaceStat.d2.R_Bytes;
1843 
1844  strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
1845  "Statistics\\D-Layer2\\R-Errors");
1846  pLib->parse_table[pLib->cur_parse_entry++].variable = \
1847  &pLib->InterfaceStat.d2.R_Errors;
1848 
1849 
1850  pLib->statistic_parse_last = pLib->cur_parse_entry - 1;
1851 }
1852 
1853 static void diva_trace_error(diva_strace_context_t *pLib,
1854  int error, const char *file, int line) {
1855  if (pLib->user_proc_table.error_notify_proc) {
1856  (*(pLib->user_proc_table.error_notify_proc))(\
1857  pLib->user_proc_table.user_context,
1858  &pLib->instance, pLib->Adapter,
1859  error, file, line);
1860  }
1861 }
1862 
1863 /*
1864  Delivery notification to user
1865 */
1866 static void diva_trace_notify_user(diva_strace_context_t *pLib,
1867  int Channel,
1868  int notify_subject) {
1869  if (pLib->user_proc_table.notify_proc) {
1871  &pLib->instance,
1872  pLib->Adapter,
1873  &pLib->lines[Channel],
1874  notify_subject);
1875  }
1876 }
1877 
1878 /*
1879  Read variable value to they destination based on the variable type
1880 */
1881 static int diva_trace_read_variable(diva_man_var_header_t *pVar,
1882  void *variable) {
1883  switch (pVar->type) {
1884  case 0x03: /* MI_ASCIIZ - syting */
1885  return (diva_strace_read_asz(pVar, (char *)variable));
1886  case 0x04: /* MI_ASCII - string */
1887  return (diva_strace_read_asc(pVar, (char *)variable));
1888  case 0x05: /* MI_NUMBER - counted sequence of bytes */
1889  return (diva_strace_read_ie(pVar, (diva_trace_ie_t *)variable));
1890  case 0x81: /* MI_INT - signed integer */
1891  return (diva_strace_read_int(pVar, (int *)variable));
1892  case 0x82: /* MI_UINT - unsigned integer */
1893  return (diva_strace_read_uint(pVar, (dword *)variable));
1894  case 0x83: /* MI_HINT - unsigned integer, hex representetion */
1895  return (diva_strace_read_uint(pVar, (dword *)variable));
1896  case 0x87: /* MI_BITFLD - unsigned integer, bit representation */
1897  return (diva_strace_read_uint(pVar, (dword *)variable));
1898  }
1899 
1900  /*
1901  This type of variable is not handled, indicate error
1902  Or one problem in management interface, or in application recodeing
1903  table, or this application should handle it.
1904  */
1905  return (-1);
1906 }
1907 
1908 /*
1909  Read signed integer to destination
1910 */
1911 static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var) {
1912  byte *ptr = (char *)&pVar->path_length;
1913  int value;
1914 
1915  ptr += (pVar->path_length + 1);
1916 
1917  switch (pVar->value_length) {
1918  case 1:
1919  value = *(char *)ptr;
1920  break;
1921 
1922  case 2:
1923  value = (short)GET_WORD(ptr);
1924  break;
1925 
1926  case 4:
1927  value = (int)GET_DWORD(ptr);
1928  break;
1929 
1930  default:
1931  return (-1);
1932  }
1933 
1934  *var = value;
1935 
1936  return (0);
1937 }
1938 
1939 static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var) {
1940  byte *ptr = (char *)&pVar->path_length;
1941  dword value;
1942 
1943  ptr += (pVar->path_length + 1);
1944 
1945  switch (pVar->value_length) {
1946  case 1:
1947  value = (byte)(*ptr);
1948  break;
1949 
1950  case 2:
1951  value = (word)GET_WORD(ptr);
1952  break;
1953 
1954  case 3:
1955  value = (dword)GET_DWORD(ptr);
1956  value &= 0x00ffffff;
1957  break;
1958 
1959  case 4:
1960  value = (dword)GET_DWORD(ptr);
1961  break;
1962 
1963  default:
1964  return (-1);
1965  }
1966 
1967  *var = value;
1968 
1969  return (0);
1970 }
1971 
1972 /*
1973  Read zero terminated ASCII string
1974 */
1975 static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var) {
1976  char *ptr = (char *)&pVar->path_length;
1977  int length;
1978 
1979  ptr += (pVar->path_length + 1);
1980 
1981  if (!(length = pVar->value_length)) {
1982  length = strlen(ptr);
1983  }
1984  memcpy(var, ptr, length);
1985  var[length] = 0;
1986 
1987  return (0);
1988 }
1989 
1990 /*
1991  Read counted (with leading length byte) ASCII string
1992 */
1993 static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var) {
1994  char *ptr = (char *)&pVar->path_length;
1995 
1996  ptr += (pVar->path_length + 1);
1997  memcpy(var, ptr + 1, *ptr);
1998  var[(int)*ptr] = 0;
1999 
2000  return (0);
2001 }
2002 
2003 /*
2004  Read one information element - i.e. one string of byte values with
2005  one length byte in front
2006 */
2007 static int diva_strace_read_ie(diva_man_var_header_t *pVar,
2008  diva_trace_ie_t *var) {
2009  char *ptr = (char *)&pVar->path_length;
2010 
2011  ptr += (pVar->path_length + 1);
2012 
2013  var->length = *ptr;
2014  memcpy(&var->data[0], ptr + 1, *ptr);
2015 
2016  return (0);
2017 }
2018 
2019 static int SuperTraceSetAudioTap(void *hLib, int Channel, int on) {
2021 
2022  if ((Channel < 1) || (Channel > pLib->Channels)) {
2023  return (-1);
2024  }
2025  Channel--;
2026 
2027  if (on) {
2028  pLib->audio_tap_mask |= (1L << Channel);
2029  } else {
2030  pLib->audio_tap_mask &= ~(1L << Channel);
2031  }
2032 
2033  /*
2034  EYE patterns have TM_M_DATA set as additional
2035  condition
2036  */
2037  if (pLib->audio_tap_mask) {
2038  pLib->trace_event_mask |= TM_M_DATA;
2039  } else {
2040  pLib->trace_event_mask &= ~TM_M_DATA;
2041  }
2042 
2043  return (ScheduleNextTraceRequest(pLib));
2044 }
2045 
2046 static int SuperTraceSetBChannel(void *hLib, int Channel, int on) {
2048 
2049  if ((Channel < 1) || (Channel > pLib->Channels)) {
2050  return (-1);
2051  }
2052  Channel--;
2053 
2054  if (on) {
2055  pLib->bchannel_trace_mask |= (1L << Channel);
2056  } else {
2057  pLib->bchannel_trace_mask &= ~(1L << Channel);
2058  }
2059 
2060  return (ScheduleNextTraceRequest(pLib));
2061 }
2062 
2063 static int SuperTraceSetDChannel(void *hLib, int on) {
2065 
2066  if (on) {
2068  } else {
2070  }
2071 
2072  return (ScheduleNextTraceRequest(pLib));
2073 }
2074 
2075 static int SuperTraceSetInfo(void *hLib, int on) {
2077 
2078  if (on) {
2079  pLib->trace_event_mask |= TM_STRING;
2080  } else {
2081  pLib->trace_event_mask &= ~TM_STRING;
2082  }
2083 
2084  return (ScheduleNextTraceRequest(pLib));
2085 }
2086 
2087 static int SuperTraceClearCall(void *hLib, int Channel) {
2089 
2090  if ((Channel < 1) || (Channel > pLib->Channels)) {
2091  return (-1);
2092  }
2093  Channel--;
2094 
2095  pLib->clear_call_command |= (1L << Channel);
2096 
2097  return (ScheduleNextTraceRequest(pLib));
2098 }
2099 
2100 /*
2101  Parse and update cumulative statistice
2102 */
2103 static int diva_ifc_statistics(diva_strace_context_t *pLib,
2104  diva_man_var_header_t *pVar) {
2106  int i, one_updated = 0, mdm_updated = 0, fax_updated = 0;
2107 
2108  for (i = pLib->statistic_parse_first; i <= pLib->statistic_parse_last; i++) {
2109  if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
2110  if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
2111  diva_trace_error(pLib, -3 , __FILE__, __LINE__);
2112  return (-1);
2113  }
2114  one_updated = 1;
2115  if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) {
2116  mdm_updated = 1;
2117  }
2118  if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) {
2119  fax_updated = 1;
2120  }
2121  }
2122  }
2123 
2124  /*
2125  We do not use first event to notify user - this is the event that is
2126  generated as result of EVENT ON operation and is used only to initialize
2127  internal variables of application
2128  */
2129  if (mdm_updated) {
2130  diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE);
2131  } else if (fax_updated) {
2132  diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE);
2133  } else if (one_updated) {
2134  diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE);
2135  }
2136 
2137  return (one_updated ? 0 : -1);
2138 }
2139 
2140 static int SuperTraceGetOutgoingCallStatistics(void *hLib) {
2142  pLib->outgoing_ifc_stats = 1;
2143  return (ScheduleNextTraceRequest(pLib));
2144 }
2145 
2146 static int SuperTraceGetIncomingCallStatistics(void *hLib) {
2148  pLib->incoming_ifc_stats = 1;
2149  return (ScheduleNextTraceRequest(pLib));
2150 }
2151 
2152 static int SuperTraceGetModemStatistics(void *hLib) {
2154  pLib->modem_ifc_stats = 1;
2155  return (ScheduleNextTraceRequest(pLib));
2156 }
2157 
2158 static int SuperTraceGetFaxStatistics(void *hLib) {
2160  pLib->fax_ifc_stats = 1;
2161  return (ScheduleNextTraceRequest(pLib));
2162 }
2163 
2164 static int SuperTraceGetBLayer1Statistics(void *hLib) {
2166  pLib->b1_ifc_stats = 1;
2167  return (ScheduleNextTraceRequest(pLib));
2168 }
2169 
2170 static int SuperTraceGetBLayer2Statistics(void *hLib) {
2172  pLib->b2_ifc_stats = 1;
2173  return (ScheduleNextTraceRequest(pLib));
2174 }
2175 
2176 static int SuperTraceGetDLayer1Statistics(void *hLib) {
2178  pLib->d1_ifc_stats = 1;
2179  return (ScheduleNextTraceRequest(pLib));
2180 }
2181 
2182 static int SuperTraceGetDLayer2Statistics(void *hLib) {
2184  pLib->d2_ifc_stats = 1;
2185  return (ScheduleNextTraceRequest(pLib));
2186 }
2187 
2189  dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
2190  STAT_PARSE_ENTRIES + \
2191  LINE_PARSE_ENTRIES + 1) * channels;
2192  return (sizeof(diva_strace_context_t) + \
2193  (parse_entries * sizeof(diva_strace_path2action_t)));
2194 }