TPlayer.h
Go to the documentation of this file.
1// -*- C++ -*-
2// Copyright (c) 2006-2010, Isode Limited, London, England.
3// All rights reserved.
4//
5// Acquisition and use of this software and related materials for any
6// purpose requires a written licence agreement from Isode Limited,
7// or a written licence from an organisation licenced by Isode Limited
8// to grant such a licence.
9
10
11//
12//
14//
16//
17// @VERSION@
18
19#ifndef _TPLAYER_H_
20#define _TPLAYER_H_
21
22#include <queue>
23
24#include "../include/cdecl.h"
25#include <isode/asn1/asn1.h>
26#include <isode/ll/TSinterface.h>
27#include <isode/messages/base.h>
28#include <isode/base/util.h>
29#include "EventSvc.h"
30
31#define TP_CLASS_0 1
32#define TP_CLASS_2 (1<<2)
33
34namespace Transport {
35
37 EVENTSVC_DLL void TSnotify (const User_ptr_t notifier);
38
40 struct TPbuffer {
41 static const unsigned TPBINC = 128;
42
43 unsigned dsize;
44 unsigned doff;
45 unsigned dlen;
46 int dfd;
47 void *mdata;
48 unsigned mlen;
49 u_char data[1];
50
51 static TPbuffer *GetNew (unsigned offset) {
52 TPbuffer *newbp = static_cast<TPbuffer *>
53 (malloc (TPBINC + sizeof (*newbp)));
54
55 if ( newbp == 0 )
56 return 0;
57
58 newbp->dsize = TPBINC;
59 newbp->doff = offset;
60 newbp->dlen = 0;
61 newbp->dfd = -1;
62 newbp->mdata = NULL;
63 newbp->mlen = 0;
64
65 return newbp;
66 }
67
68 void Free() {
69 if ( dfd > 0 ) close (dfd);
70 if ( mdata != NULL )
71 isode_munmap(mdata, mlen);
72 free (this);
73 }
74
76 // returns NULL if no memory
77 static inline TPbuffer *Add (TPbuffer *bufp,
78 const u_char *bytes,
79 unsigned len) {
80 unsigned newlen = bufp->doff + bufp->dlen + len;
81
82 if ( bufp->dsize < newlen ) {
83 unsigned newsize = bufp->dsize + TPBINC;
84 if ( newsize < newlen )
85 newsize = newlen + TPBINC;
86
87 TPbuffer *newbp = static_cast<TPbuffer *>
88 (realloc (bufp, sizeof (*bufp) + newsize));
89
90 if ( newbp == 0 ) {
91 MSG_Base_Nomem_LOG (sizeof (*bufp) + newsize);
92 free (bufp);
93 return 0;
94 }
95
96 bufp = newbp;
97 bufp->dsize = newsize;
98 }
99
100 memcpy (bufp->data + bufp->doff + bufp->dlen, bytes, len);
101
102 bufp->dlen += len;
103
104 return bufp;
105 }
106 };
107
109 class TStimer : public Event::AsyncEvent {
110 private:
111 Provider *provider;
112
113 public:
114 virtual ~TStimer() { Cancel(); }
115
116 void Init (Provider *p) {
117 provider = p;
118 }
119
120 virtual void Deliver () {
121 provider->Deliver (this);
122 }
123
124 void Send (int secs) {
125 if ( secs > 0 )
126 Event::Manager::GetManager()->QueueAt (this, 1000*secs);
127 else
128 Event::Manager::GetManager()->Queue (this);
129 }
130 };
131
132
134 class Layer2Net {
135 public:
136 virtual ~Layer2Net() {}
137
139 virtual void ConnectRequest (
140 struct NSAPaddr &calling,
141 struct NSAPaddr &called) = 0;
142
144 virtual void Deliver (TPbuffer **data) = 0;
145
147 virtual void DisconnectRequest (bool force = true) = 0;
148 };
149
151 // Limited to the facilities needed for RFC 2126
152
153 class Layer {
154 public:
165
166 private:
167 static EVENTSVC_DLL pthread_mutex_t refmutex;
168 static EVENTSVC_DLL unsigned refvalue;
169
170 Layer2Net *net;
171 Provider *provider;
172
173 ConnectRequest connect;
174
175 unsigned classes;
176 unsigned maxtpdu;
177 unsigned offset;
178 unsigned srcref;
179 unsigned dstref;
180
181 bool useprefsize;
182
183 enum State state;
184
186 void TDISind (DisconnectIndication &disind) {
187 if ( provider->GetUser () ) {
188 TSnotify (provider->GetUser()->Deliver (&disind));
189 provider->ClearUser();
190 }
191 }
192
194 TPbuffer *GetBuffer () {
195 TPbuffer *bufp = TPbuffer::GetNew (offset);
196 if ( bufp == 0 ) {
197 InternalError (DR_congestion, "out of memory");
198 return 0;
199 } else {
200 return bufp;
201 }
202 }
203
205 void WritePDU (TPbuffer *bufp) {
206 // As writes from Transport are not synchronized,
207 // it could happen that net changes between the test and use.
208 Layer2Net *tmpn = net;
209 if ( state != CLOSED && tmpn != 0 )
210 tmpn->Deliver (&bufp);
211 else
212 bufp->Free();
213 }
214
215 // PDU generation
217 // Uses data in already in object
218 void makeCR ();
219
221 // Uses data in already in object
222 void makeCC ();
223
225 // Not able to specify additional information at the moment
226 void makeDR (enum DRreason reason,
227 const char *data,
228 unsigned cc);
229
231 void makeDC ();
232
234 void makeDT (const struct udvec *uv, bool eot);
235
237 void makeED (const u_char *data, unsigned len);
238
240 enum RejectCause {
241 Reject_NotSpecified = 0,
242 Reject_InvalidParameterCode = 1,
243 Reject_InvalidTPDUtype = 2,
244 Reject_InvalidParameterValue = 3
245 };
246
248 void makeER (enum RejectCause cause,
249 const u_char *tpdu, unsigned len);
250
251 // PDU handling
252 void getCR (struct qbuf *qb);
253 void getCC (struct qbuf *qb);
254 void getDR (struct qbuf *qb);
255 void getDC (struct qbuf *qb);
256 void getDT (struct qbuf *qb);
257 void getED (struct qbuf *qb);
258 void getER (struct qbuf *qb);
259
261 void ProtocolError (struct qbuf *qb,
262 int offset,
263 enum RejectCause cause);
264
266 void InternalError (enum DRreason reason, const char *text);
267
269 void SendUserDR (enum DRreason reason,const char *text);
270
272 bool DstRefOK (struct qbuf *qb) {
273 uint16_t ref = ((qb->qb_data[2] &0xFF)<<8)|(qb->qb_data[3]&0xFF);
274 if ( ref == srcref ) return true;
275 InternalError (DR_reference, "Invalid DST-REF in TPDU");
276 return false;
277 }
278
280 void CloseNetwork () {
281 if ( net == 0 ) return;
282 net->DisconnectRequest(false);
283 net = 0;
284 state = CLOSED;
285 }
286
287 public:
288 Layer (int off) :
289 net(0), provider(0),
290 classes (TP_CLASS_0), maxtpdu(8192), offset(off),
291 useprefsize(false), state(CLOSED) {
292 pthread_mutex_lock (&refmutex);
293 ++refvalue;
294 if (refvalue > 0xFFFF)
295 refvalue = 1; // reset
296 srcref = refvalue;
297 pthread_mutex_unlock (&refmutex);
298 memset (&connect, 0, sizeof connect);
299 }
300
301 EVENTSVC_DLL ~Layer();
302
304 void SetInbound() { state = WFCR; }
305
307 void SetLink (Provider *pp, Layer2Net *np) {
308 net = np;
309 provider = pp;
310 }
311
313 void Configure (unsigned maxt, unsigned cls) {
314 if ( maxtpdu != 0 )
315 maxtpdu = maxt;
316
317 if ( cls != 0 )
318 classes = cls & (TP_CLASS_0|TP_CLASS_2);
319 }
320
322 EVENTSVC_DLL void Deliver (ConnectRequest *req);
323
325 EVENTSVC_DLL void Deliver (ConnectResponse *req);
326
328 EVENTSVC_DLL void Deliver (DataRequest *req);
329
331 EVENTSVC_DLL void Deliver (DisconnectRequest *data);
332
334 void NetworkConnect (NSAPaddr &calling, NSAPaddr &called) {
335 connect.calling.ta_addr = calling;
336 connect.called.ta_addr = called;
337 }
338
340 EVENTSVC_DLL void NetworkRead (struct qbuf *qb);
341
343 // returns true if network closed or closing
344 EVENTSVC_DLL bool NetworkStatus (MSGstruct *msp);
345
347 EVENTSVC_DLL void GetSaveInfo (char *buffer, size_t buflen);
348
350 // returns false if failed
351 EVENTSVC_DLL bool SetSaveInfo (const char *buffer);
352
354 EVENTSVC_DLL void SendConnectIndication ();
355 };
356}
357
358
359#endif /* _TPLAYER_H_ */
EVENTSVC_DLL void TSnotify(const User_ptr_t notifier)
Send a notification to the transport service used via the Event Manager.
Definition TPlayer.C:1534
#define TP_CLASS_0
Provides a Class 0 and Class 2 interface layer.
Definition TPlayer.h:31
Class giving interface from Layer to Network interface.
Definition TPlayer.h:134
virtual void ConnectRequest(struct NSAPaddr &calling, struct NSAPaddr &called)=0
Connect networks.
virtual void Deliver(TPbuffer **data)=0
Write NSDU.
virtual void DisconnectRequest(bool force=true)=0
Disconnect Network connection.
Class for handling Class 0 and Class 2 Transport.
Definition TPlayer.h:153
EVENTSVC_DLL void Deliver(ConnectRequest *req)
TCONreq.
Definition TPlayer.C:83
void NetworkConnect(NSAPaddr &calling, NSAPaddr &called)
Initialize from network connection for inbound connection.
Definition TPlayer.h:334
EVENTSVC_DLL void NetworkRead(struct qbuf *qb)
Handle data from network.
Definition TPlayer.C:244
EVENTSVC_DLL void GetSaveInfo(char *buffer, size_t buflen)
Get save information from layer.
Definition TPlayer.C:524
void Configure(unsigned maxt, unsigned cls)
Configure.
Definition TPlayer.h:313
@ WFCR
Wait for network Connect.
Definition TPlayer.h:158
@ WFTRESP
Release in progress.
Definition TPlayer.h:163
@ WFNC
Closed.
Definition TPlayer.h:157
@ WBCL
Wait for CC-TPDU.
Definition TPlayer.h:160
@ CLOSING
Transport connection is open.
Definition TPlayer.h:162
@ OPEN
Wait before releasing.
Definition TPlayer.h:161
@ WFCC
Wait for CR-TPDU.
Definition TPlayer.h:159
EVENTSVC_DLL bool NetworkStatus(MSGstruct *msp)
Network status indication.
Definition TPlayer.C:306
void SetInbound()
Set as inbound Layer.
Definition TPlayer.h:304
EVENTSVC_DLL bool SetSaveInfo(const char *buffer)
Set state from save info.
Definition TPlayer.C:545
void SetLink(Provider *pp, Layer2Net *np)
Set the links.
Definition TPlayer.h:307
EVENTSVC_DLL void SendConnectIndication()
Send TS user a connect indication.
Definition TPlayer.C:752
Transport layer timer.
Definition TPlayer.h:109
Extensible buffer, used to prepare outgoing TPDUs.
Definition TPlayer.h:40
unsigned doff
Offset at which Layer starts writing.
Definition TPlayer.h:44
u_char data[1]
Data, actually extensible.
Definition TPlayer.h:49
unsigned dsize
Total size of buffer.
Definition TPlayer.h:43
static TPbuffer * Add(TPbuffer *bufp, const u_char *bytes, unsigned len)
Add bytes to buffer.
Definition TPlayer.h:77
unsigned dlen
Current length of data from doff.
Definition TPlayer.h:45
int dfd
FD of backing file, or -1 if none.
Definition TPlayer.h:46
unsigned mlen
Length of mmapped data (if any)
Definition TPlayer.h:48
void * mdata
Start address of mmapped data (if any)
Definition TPlayer.h:47

All rights reserved © 2002 - 2024 Isode Ltd.