File: CapiBase.cpp

package info (click to toggle)
capi4hylafax 1%3A01.02.03-10sarge2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,856 kB
  • ctags: 2,966
  • sloc: cpp: 20,126; sh: 7,703; makefile: 215; perl: 36
file content (189 lines) | stat: -rw-r--r-- 7,633 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*---------------------------------------------------------------------------*\

    Copyright (C) 2000 AVM GmbH. All rights reserved.

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY, without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, and WITHOUT
    ANY LIABILITY FOR ANY DAMAGES arising out of or in connection
    with the use or performance of this software. See the
    GNU General Public License for further details.

\*---------------------------------------------------------------------------*/

#include "CapiBase.h"
#include "c2msgdef.h"
#include "dbgLINUX.h"

#define __NO_CAPIUTILS__
#include <capi20.h>
#include <pthread.h>

/*---------------------------------------------------------------------------*\
\*---------------------------------------------------------------------------*/

struct InternalCapiEntry {
    CCallBackCapiBase *pBaseClass;
    pthread_t          Thread;
    tBool              StopThread;
};

static void *CapiBase_WaitForSignalThread (InternalCapiEntry *pice);


/*===========================================================================*\
\*===========================================================================*/

void CapiBase_Register (CCallBackCapiBase *pBaseClass, tUInt, tUInt MaxB3Connection, tUInt MaxB3Blks,
                        tUInt MaxSizeB3) {
    dhead ("CapiBase_Register", DCON_CapiBase);
    dassert (pBaseClass != 0);
    c_info             fret = ci_Int_MemoryFullErr;
    InternalCapiEntry *pice = new InternalCapiEntry;
    dwarning (pice != 0);
    pBaseClass->Set_ApplID (IllegalApplID);
    if (pice) {
        pice->pBaseClass = pBaseClass;
        pice->Thread     = 0;
        pice->StopThread = vFalse;
        fret = (c_info)capi20_isinstalled();
        if (fret == ci_NoError) {
            tUInt applid;
            fret = (c_info)capi20_register (MaxB3Connection, MaxB3Blks, MaxSizeB3, &applid);
            dprint ("ApplID=%x, Register-Return=%x ", applid, fret);
            if ((applid != IllegalApplID) && (CapiInfoIsSuccess (ci_NoError))) {
                pBaseClass->Set_ApplID (applid);
                if (!pthread_create (&pice->Thread, 0, (void *(*)(void *))CapiBase_WaitForSignalThread, pice)) {
                    // everything is initialised successfully
                    return;
                }
                dwarning (0);
                pBaseClass->Set_ApplID (IllegalApplID);
                fret  = (c_info)capi20_release (applid);
                // what can we do if release failed?
                dassert (fret == ci_NoError);
                fret = ci_Reg_OSResourceErr;
            }
        }
        delete pice;
    }
    dassert (fret != ci_NoError);
    pBaseClass->RegisterComplete (vIllegalHandle, fret);
}


/*===========================================================================*\
\*===========================================================================*/

void CapiBase_Release (thCapiBase Base) {
    dhead ("CapiBase_Release", DCON_CapiBase);
    dassert (Base != vIllegalHandle);
    InternalCapiEntry *pice = (InternalCapiEntry *)Base;
    dassert (pice->pBaseClass->ApplID() != IllegalApplID);
    c_word applid           = pice->pBaseClass->ApplID();
    pice->pBaseClass->Set_ApplID (IllegalApplID);
    pice->StopThread        = vTrue;
    dprint ("Terminate Thread(%x)!!! ", pice->pBaseClass);

    // send a message to terminate the CAPI_WAIT_FOR_SIGNAL
    static c_word ListenMsg[] = { 0x1a, 0x00, CAPI_LISTEN_REQ, 0x00,
                                  0x01, 0x00, 0x00, 0x00,
                                  0x00, 0x00, 0x00, 0x00, 0x00 };
    capi20_put_message (applid, (c_message)ListenMsg);
    // Call to CAPI_RELEASE will be done at the end of the thread
}


/*===========================================================================*\
\*===========================================================================*/

void CapiBase_PutMessage (thCapiBase Base, c_message Message) {
    dhead ("CapiBase_PutMessage", DCON_CapiBase);
    dassert (Base != vIllegalHandle);
    ((InternalCapiEntry *)Base)->pBaseClass->PutMessageComplete ((c_info)capi20_put_message (
                ((InternalCapiEntry *)Base)->pBaseClass->ApplID(), Message));
}


/*===========================================================================*\
\*===========================================================================*/

void CapiBase_GetProfile (thCapiBase Base, tUInt Controller) {
    dhead ("CapiBase_GetProfile", DCON_CapiBase);
    dassert (Base != vIllegalHandle);
    cm_getprofile Buffer;
    ((InternalCapiEntry *)Base)->pBaseClass->GetProfileComplete (Controller, &Buffer,
                (c_info)capi20_get_profile (Controller, (c_message)&Buffer));
}


/*===========================================================================*\
\*===========================================================================*/

void *CapiBase_WaitForSignalThread (InternalCapiEntry *pice) {
    dhead ("CapiBase_WaitForSignalThread", DCON_CapiBase);
    dassert (pice != 0);
    c_message pCAPIMessage;
    c_word    applid = pice->pBaseClass->ApplID();
    tUInt     fret   = ci_NoError;
    dassert (applid != IllegalApplID);
    if (pice->StopThread == vFalse) {
        pice->pBaseClass->RegisterComplete ((thCapiBase)pice, ci_NoError);
        while (pice->StopThread == vFalse) {
            // after the ThreadState was checked, check the result from CAPI_WAIT_FOR_SIGNAL
            switch (fret) {
            case ci_NoError:
            case ci_Reg_Busy:
            case ci_Msg_Busy:
            case ci_Msg_SendQueueFull:
            case ci_Msg_ReceiveQueueEmpty:
                break;
            default:
                /*----- Ein schwieriger Fehler! -----*/
                dwarning (0);
                pice->pBaseClass->GetMessageReceived (0, (c_info)fret);
                break;
            }
            dprint ("-CAPI_GET_MESSAGE(%x)- ", pice->pBaseClass);
            fret = capi20_get_message (applid, &pCAPIMessage);
            switch (fret) {
            case ci_Reg_Busy:
            case ci_Msg_Busy:
            case ci_Msg_SendQueueFull:
            case ci_Msg_ReceiveQueueEmpty:
                break;
            default:
                dwarning (0);
                // no break!
            case ci_NoError:
                pice->pBaseClass->GetMessageReceived (pCAPIMessage, (c_info)fret);
                break;
            }
            if (pice->StopThread == vTrue) {
                dprint ("Release was called in GetMessageReceived(%x)! ", pice->pBaseClass);
                break;
            }
            dprint ("-CAPI_WAIT_FOR_SIGNAL(%x)- ", pice->pBaseClass);
            fret = capi20_waitformessage (applid, 0);
            dprint ("-loop(%x)- ", pice->pBaseClass);
        }
    }
    dprint ("Call CAPI_RELEASE!! ");
    dassert (pice->pBaseClass->ApplID() == IllegalApplID);
    fret = capi20_release (applid);
    dassert (fret == 0);
    dprint ("-ThreadQueueEnd(%x)- ", pice->pBaseClass);
    CCallBackCapiBase *pBaseClass = pice->pBaseClass;
    delete pice;
    pBaseClass->ReleaseComplete();
    return 0;
}


/*===========================================================================*\
\*===========================================================================*/