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