1 /*! \file beepchannel.h
2  *  \brief global objects and defines
3  *
4  * \author  Rainer Gerhards <rgerhards@adiscon.com>
5  * \date    2003-08-04
6  *
7  * \date    2003-09-04
8  *          Updated to support multiple client profiles.
9  *
10  * \date    2003-09-08
11  *          Added support for sending SEQs in reply to the server's
12  *          response.
13  *
14  * Copyright 2002-2014
15  *     Rainer Gerhards and Adiscon GmbH. All Rights Reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met:
20  *
21  *     * Redistributions of source code must retain the above copyright
22  *       notice, this list of conditions and the following disclaimer.
23  *
24  *     * Redistributions in binary form must reproduce the above copyright
25  *       notice, this list of conditions and the following disclaimer in
26  *       the documentation and/or other materials provided with the
27  *       distribution.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
30  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
32  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
33  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 #ifndef __LIB3195_BEEPCHANNEL_H_INCLUDED__
42 #define __LIB3195_BEEPCHANNEL_H_INCLUDED__ 1
43 #include "sockets.h"
44 #include "beepsession.h"
45 
46 /** Invalid channel number (no valid channel value) */
47 #define SBCHAN_INVALID_CHANNEL -1
48 #define sbChanCHECKVALIDOBJECT(x) {assert((x) != NULL); assert((x)->OID == OIDsbChan); assert((x)->iState != sbChan_STATE_INVALID);}
49 
50 /**
51  * The status of the channel. We may not need all of these
52  * values - so far defined those that we think to be useful.
53  */
54 enum sbChannelState_				/** return value. All methods return this if not specified otherwise */
55 {
56 	sbChan_STATE_INVALID = 0,		/**< should never occur, indicates a program error */
57 	sbChan_STATE_INITIALIZED,		/**< The channel object is initialized, but the channel not yet opened */
58 	sbChan_STATE_OPEN,				/**< channel is open and ready for data communication */
59 	sbChan_STATE_AWAITING_CLOSE,	/**< peer has indicated processing is done, channel is awaiting close command */
60 	sbChan_STATE_PENDING_CLOSE,		/**< close is pending, but not yet completed (one peer send a close request) */
61 	sbChan_STATE_CLOSED,			/**< channel is closed. Next thing is to do an ordinary destroy */
62 	sbChan_STATE_BROKEN,			/**< for some (unkonw reason) the channel does not work any longer. Must abort session. */
63 	sbChan_STATE_ERR_FREE_NEEDED	/**< for some (unkonw reason) the channel does not work any longer. The channel object shall be freed by the destructor (but is not yet). */
64 };
65 typedef enum sbChannelState_ sbChannelState;
66 
67 struct sbMesgObject;
68 struct sbSessObject;
69 struct sbChanObject
70 /** The BEEP channel object. Implemented via \ref beepchannel.h and
71  *  \ref beepchannel.c.
72  */
73 {
74 	srObjID OID;			/**< object ID */
75 	unsigned uChanNum;		/**< BEEP-assigned channel number */
76 	unsigned uSeqno;		/**< current seqno */
77 	unsigned uMsgno;		/**< current msgno */
78 	unsigned uTXWin;		/**< maximum transmit window */
79 	unsigned uTXWinLeft;	/**< remaining bytes left in current tx window */
80 	unsigned uRXWin;		/**< maximum receive window */
81 	unsigned uRXWinLeft;	/**< remaining bytes left in current rx window */
82 	sbSockObj* pSock;		/**< associated socket object */
83 	struct sbSessObject* pSess;/**< associated session */
84 	sbChannelState iState;	/**< channel status */
85 	void *pProfInstance;	/**< pointer to associated profile instance data (to be used by the profile, if needed) */
86 	struct sbProfObject *pProf;	/**< associated profile */
87 };
88 typedef struct sbChanObject sbChanObj;
89 
90 #include "beepmessage.h"
91 
92 /**
93  * Set the channel number for this channel (done by channel 0 profile).
94  *
95  * IMPORTANT: the channel number MUST be set only ONCE and this
96  *            BEFORE any data is sent or received over the channel.
97  *            The reason for this is that this method also
98  *            adds the channel to session's list of channel
99  *            objects. If it would be called multiple times,
100  *            multiple copies would be present in the list - which
101  *            would (mildly said) cause unpredictable results).
102  *
103  *            Of course, we could change the behaviour to handle
104  *            this case, but I do not see any good reason for this.
105  *            So far, it looks like a waste of CPU cycles...
106  *
107  * \param iChanno [in] Channel number to be used on this channel.
108  */
109 srRetVal sbChanSetChanno(sbChanObj *pThis, int iChanno);
110 
111 /** sbChan Constructor.
112  * \param pSock [in] pointer to socket to use. Can not be NULL.
113  * \retval Pointer to channel object or NULL, if error occured.
114  */
115 sbChanObj* sbChanConstruct(struct sbSessObject* pSess);
116 
117 /**
118  * Send a BEEP frame on this channel.
119  * The message provided as parameter is sent over the channel. This
120  * method here performs all necessary processing, including
121  * conversion from Mesg to (eventually multiple) frames.
122  *
123  * \param pMesg Pointer to the Mesg to be sent.
124  *
125  * \param szCmd Command to send (e.g. "ANS", "MSG", ...). Can
126  *        not be NULL.
127  */
128 srRetVal sbChanSendMesg(sbChanObj *pThis, struct sbMesgObject* pMesg, char* pszCmd);
129 
130 /**
131  * Actually send the frame over the channel.
132  * We need to first check if the frame is within the current Window
133  * and - if not - we need to return immediately to the caller. The
134  * session layer will then handle the rest.
135  *
136  * For full details on the send process, see \ref architecture.c
137  *
138  * \param pFram [in] pointer to to-be-sent frame
139  * \retval The usual values, but let's point out that
140  *         SR_RET_REMAIN_WIN_TOO_SMALL must be returned if the
141  *         remaining window is too small to send the frame.
142  */
143 srRetVal sbChanActualSendFram(sbChanObj *pThis, struct sbFramObject* pFram);
144 
145 
146 /**
147  * Destructor. The channel object itself will
148  * be freed and can not be used any longer.
149  */
150 void sbChanDestroy(sbChanObj* pThis);
151 
152 /**
153  * Update the channel status.
154  *
155  * \param iNewState new channel status
156  */
157 srRetVal sbChanUpdateChannelState(sbChanObj* pThis, int iNewState);
158 
159 /**
160  * Assign a profile to this channel. Only one profile
161  * can be assigned to a channel at one time. As such,
162  * no profile is allowed to be already assigned when
163  * this method is called.
164  *
165  * Once the profile object has been assigned to the
166  * channel, the channel "owns" it. That means the caller
167  * is not allowed to use it any longer or free() it.
168  * The channel will free it when the channel is destroyed.
169  *
170  * \param pProf Profile to be assigned.
171  */
172 srRetVal sbChanAssignProfile(sbChanObj *pThis, struct sbProfObject *pProf);
173 
174 /**
175  * Aborts a channel. That is, it destroys
176  * the channel object itself but DOES NOT remove
177  * it from the session's linked list of channels.
178  */
179 void sbChanAbort(sbChanObj* pThis);
180 
181 /**
182  * Send an error response to the remote peer.
183  *
184  * \param uErrCode numeric error code as of RC 3080
185  * \param pszErrMsg human-readable error message string. MUST
186  *        NOT be NULL.
187  */
188 srRetVal sbChanSendErrResponse(sbChanObj *pThis, unsigned uErrCode, char* pszErrMsg);
189 
190 /**
191  * Set the channel status to "awaiting close".
192  */
193 srRetVal sbChanSetAwaitingClose(sbChanObj* pThis);
194 
195 /**
196  * Send a SEQ frame for the current channel.
197  *
198  * \param pChan Channel this SEQ is for.
199  * \param uAckno ackno to use in the SEQ. Can not be 0.
200  * \param uWindow Window to use in the SEQ. If 0, use BEEP default.
201  */
202 srRetVal sbChanSendSEQ(sbChanObj *pThis, unsigned uAckno, unsigned uWindow);
203 
204 /**
205  * Send an OK on the associated channel. This is
206  * just a shortcut to save some typing.
207  */
208 srRetVal sbChanSendOK(sbChanObj*pThis, void (*OnFrameDestroy)(struct sbFramObject*), void* pUsr);
209 
210 /**
211  * Set channel state to closed.
212  */
213 srRetVal sbChanSetChanClosed(sbChanObj* pThis);
214 
215 #endif
216