1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**  NAME
80**
81**      cnclsm.h
82**
83**  FACILITY:
84**
85**      Remote Procedure Call (RPC)
86**
87**  ABSTRACT:
88**
89**  Definitions of types/constants internal to the NCA Connection
90**  RPC Protocol Service client call state machine.
91**
92**
93*/
94
95#ifndef _CNCALLSM_H
96#define _CNCALLSM_H 1
97
98/***********************************************************************/
99/*
100 * C L I E N T   C A L L   S T A T E S
101 */
102/*
103 * State values are incremented by 100 to distinguish them from
104 * action routine indexes which are all < 100.  This was done as
105 * an efficiency measure to the engine, rpc__cn_sm_eval_event().
106 */
107#define RPC_C_CLIENT_CALL_INIT              100
108#define RPC_C_CLIENT_CALL_ASSOC_ALLOC_WAIT  101
109#define RPC_C_CLIENT_CALL_STUB_WAIT         102
110#define RPC_C_CLIENT_CALL_REQUEST           103
111#define RPC_C_CLIENT_CALL_RESPONSE          104
112#define RPC_C_CLIENT_CALL_CALL_COMPLETED    105
113#define RPC_C_CLIENT_CALL_CFDNE             106
114#define RPC_C_CLIENT_CALL_CALL_FAILED       107
115#define RPC_C_CLIENT_CALL_STATES            108
116
117/***********************************************************************/
118/*
119 * C L I E N T / S E R V E R   C A L L   E V E N T S
120 */
121
122/*
123 * Events common to both client and server state machines
124 */
125#define RPC_C_CALL_SEND                     100
126#define RPC_C_CALL_TRANSMIT_REQ             100    /* client */
127#define RPC_C_CALL_RPC_RESP                 100    /* server */
128#define RPC_C_CALL_RECV                     101
129#define RPC_C_CALL_RPC_CONF                 101   /* client */
130#define RPC_C_CALL_RPC_IND                  101   /* server */
131#define RPC_C_CALL_FAULT_DNE                102
132#define RPC_C_CALL_FAULT                    103
133#define RPC_C_CALL_LOCAL_ALERT              104
134#define RPC_C_CALL_END                      105
135
136/*
137 * Events only applicable to client state machine
138 */
139#define RPC_C_CALL_ALLOC_ASSOC_ACK          106
140#define RPC_C_CALL_ALLOC_ASSOC_NAK          107
141#define RPC_C_CALL_START_CALL               108
142#define RPC_C_CALL_LAST_TRANSMIT_REQ        109
143#define RPC_C_CALL_LOCAL_ERR                110
144#define RPC_C_CALL_ALERT_TIMEOUT            111
145#define RPC_C_CALL_CLIENT_EVENTS            112
146
147/*
148 * Events only applicable to server state machine
149 */
150#define RPC_C_CALL_REMOTE_ALERT_IND         106
151#define RPC_C_CALL_ORPHANED                 107
152#define RPC_C_CALL_SERVER_EVENTS            108
153
154/***********************************************************************/
155/*
156 * C L I E N T   C A L L   T A B L E S
157 */
158EXTERNAL rpc_cn_sm_state_entry_p_t rpc_g_cn_client_call_sm [];
159EXTERNAL rpc_cn_sm_action_fn_t rpc_g_cn_client_call_action_tbl [];
160
161#ifdef DEBUG
162EXTERNAL const char   *rpc_g_cn_call_client_events [];
163EXTERNAL const char   *rpc_g_cn_call_client_states [];
164#endif
165
166/***********************************************************************/
167/*
168 * S E R V E R   C A L L   S T A T E S
169 */
170#define RPC_C_SERVER_CALL_INIT              100
171#define RPC_C_SERVER_CALL_CALL_REQUEST      101
172#define RPC_C_SERVER_CALL_CALL_RESPONSE     102
173#define RPC_C_SERVER_CALL_CALL_COMPLETED    103
174
175/***********************************************************************/
176/*
177 * S E R V E R   C A L L   T A B L E S
178 */
179EXTERNAL rpc_cn_sm_state_entry_p_t rpc_g_cn_server_call_sm [];
180EXTERNAL rpc_cn_sm_action_fn_t     rpc_g_cn_server_call_action_tbl [];
181
182#ifdef DEBUG
183EXTERNAL const char   *rpc_g_cn_call_server_events [];
184EXTERNAL const char   *rpc_g_cn_call_server_states [];
185#endif
186
187/*
188 * Action routine to invoke in case of a protocol error detected
189 * during an illegal state transition.
190 */
191PRIVATE unsigned32     rpc__cn_call_sm_protocol_error (
192        dce_pointer_t /* sc_struct */,
193        dce_pointer_t /* event_param */,
194	dce_pointer_t /* sm		 */
195    );
196
197
198#ifdef DEBUG
199
200#define RPC_CN_CALL_CLIENT_STATE(state) ( \
201    rpc_g_cn_call_client_states[ (state) - RPC_C_CN_STATEBASE ] \
202)
203
204#define RPC_CN_CALL_CLIENT_EVENT(event_id) ( \
205    rpc_g_cn_call_client_events[ (event_id) - RPC_C_CN_STATEBASE ] \
206)
207
208#define RPC_CN_CALL_SERVER_STATE(state) ( \
209    rpc_g_cn_call_server_states[ (state) - RPC_C_CN_STATEBASE ] \
210)
211
212#define RPC_CN_CALL_SERVER_EVENT(event_id) ( \
213    rpc_g_cn_call_server_events[ (event_id) - RPC_C_CN_STATEBASE ] \
214)
215
216#endif
217/***********************************************************************/
218/*
219 * R P C _ C N _ C A L L _ S M _ T R C
220 */
221#ifdef DEBUG
222
223PRIVATE void rpc__cn_call_sm_trace (
224    rpc_cn_call_rep_t *         /* call rep */,
225    unsigned32                  /* event_id */,
226    unsigned32                  /* id */,
227    const char *                /* file */,
228    const char *                /* funcname */,
229    int                         /* lineno */);
230
231#define RPC_CN_CALL_SM_TRC(crep, event_id, id) \
232    rpc__cn_call_sm_trace(crep, event_id, id, __FILE__, __func__, __LINE__)
233
234#else
235
236#define RPC_CN_CALL_SM_TRC(crep, event_id, id)
237
238#endif
239
240
241/***********************************************************************/
242/*
243 * R P C _ C N _ C A L L _ S M _ T R C _ S T A T E
244 */
245#ifdef DEBUG
246
247PRIVATE void rpc__cn_call_sm_trace_state (
248    rpc_cn_call_rep_t *         /* call rep */,
249    unsigned32                  /* id */,
250    const char *                /* file */,
251    const char *                /* funcname */,
252    int                         /* lineno */);
253
254#define RPC_CN_CALL_SM_TRC_STATE(crep, id) \
255    rpc__cn_call_sm_trace_state(crep, id, __FILE__, __func__, __LINE__)
256
257#else
258
259#define RPC_CN_CALL_SM_TRC_STATE(crep, id)
260
261#endif
262
263/***********************************************************************/
264/*
265 * R P C _ C N _ P O S T _ C A L L _ S M _ E V E N T
266 *
267 * Posts an event to either a server or client call state machine.
268 *
269 * Sample usage:
270 *
271 *
272 *    rpc_cn_assoc_p_t          assoc;
273 *    unsigned8                 event;
274 *    rpc_cn_fragbuf_p_t        fragbuf;
275 *    unsigned32                st;
276 *
277 * RPC_CN_POST_CALL_SM_EVENT (assoc, event, fragbuf, st);
278 */
279
280#define RPC_CN_POST_CALL_SM_EVENT(assoc, event_id, fragbuf, st) \
281{ \
282    rpc_cn_call_rep_p_t crep; \
283\
284    crep = RPC_CN_ASSOC_CALL (assoc); \
285    if (crep != NULL) \
286    { \
287        if (RPC_CN_PKT_CALL_ID ((rpc_cn_packet_p_t) RPC_CN_CREP_SEND_HDR (crep)) \
288            == \
289            RPC_CN_PKT_CALL_ID (RPC_CN_FRAGBUF_PKT_HDR (fragbuf))) \
290        { \
291            RPC_CN_CALL_SM_TRC (crep, event_id, (RPC_CN_PKT_CALL_ID ((rpc_cn_packet_p_t) RPC_CN_CREP_SEND_HDR (crep))));\
292            st = rpc__cn_sm_eval_event (event_id, (dce_pointer_t) fragbuf, \
293                 (dce_pointer_t) crep, &(crep->call_state)); \
294            RPC_CN_CALL_SM_TRC_STATE (crep, (RPC_CN_PKT_CALL_ID ((rpc_cn_packet_p_t) RPC_CN_CREP_SEND_HDR (crep)))); \
295        } \
296        else \
297        { \
298            (*fragbuf->fragbuf_dealloc)(fragbuf); \
299        } \
300    } \
301    else \
302    { \
303        (*fragbuf->fragbuf_dealloc)(fragbuf); \
304    } \
305}
306
307/***********************************************************************/
308/*
309 * R P C _ C N _ P O S T _ F I R S T _ C A L L _ S M _ E V E N T
310 *
311 * Posts the first [server] event to the call state machine.
312 * This differs from the normal post call sm event because the
313 * callid field has not been initialized upon the first server
314 * event.
315 *
316 * Sample usage:
317 *
318 *    rpc_cn_call_rep_p_t       crep;
319 *    rpc_cn_assoc_p_t          assoc;
320 *    unsigned8                 event;
321 *    rpc_cn_fragbuf_p_t        fragbuf;
322 *    unsigned32                st;
323 *
324 * RPC_CN_POST_FIRST_CALL_SM_EVENT (crep, assoc, event, fragbuf, st);
325 */
326
327#define RPC_CN_POST_FIRST_CALL_SM_EVENT(crep, assoc, event_id, fragbuf, st) \
328{ \
329    rpc__cn_assoc_alloc ((assoc), &(st));\
330    if (st == rpc_s_ok)\
331    {\
332        RPC_CN_CALL_SM_TRC (crep, event_id, (RPC_CN_PKT_CALL_ID (RPC_CN_FRAGBUF_PKT_HDR (fragbuf))));\
333        st = rpc__cn_sm_eval_event (event_id, (dce_pointer_t)fragbuf, \
334             (dce_pointer_t)(crep), &((crep)->call_state)); \
335        RPC_CN_CALL_SM_TRC_STATE (crep, (RPC_CN_PKT_CALL_ID ((rpc_cn_packet_p_t) RPC_CN_CREP_SEND_HDR (crep))));\
336    }\
337}
338
339/***********************************************************************/
340/*
341 * R P C _ C N _ C A L L _ E V A L _ E V E N T
342 *
343 * Posts an event from either a client caller or server call
344 * executor thread to the call state machine.
345 *
346 * Sample usage:
347 *
348 *    rpc_cn_call_rep_p_t       crep;
349 *    unsigned8                 event;
350 *    dce_pointer_t                 spc_struct;
351 *    unsigned32                st;
352 *
353 * RPC_CN_CALL_EVAL_EVENT (event_id, spc_struct, crep, st);
354 */
355
356#define RPC_CN_CALL_EVAL_EVENT(event_id, spc_struct, crep, st)\
357{ \
358    RPC_CN_CALL_SM_TRC (crep, event_id, (RPC_CN_PKT_CALL_ID ((rpc_cn_packet_p_t) RPC_CN_CREP_SEND_HDR (crep))));\
359    st = rpc__cn_sm_eval_event ((event_id), (dce_pointer_t)(spc_struct), \
360                                (dce_pointer_t)(crep), \
361                                &(crep)->call_state); \
362    RPC_CN_CALL_SM_TRC_STATE (crep, (RPC_CN_PKT_CALL_ID ((rpc_cn_packet_p_t) RPC_CN_CREP_SEND_HDR (crep)))); \
363}
364
365
366/***********************************************************************/
367/*
368 * R P C _ C N _ C A L L _ I N S E R T _ E V E N T
369 *
370 * This macro will be called when an event is generated inside an
371 * action routine of the call state machine.
372 */
373#define RPC_CN_CALL_INSERT_EVENT(crep, event)\
374{\
375    RPC_DBG_PRINTF (rpc_e_dbg_cn_state, RPC_C_CN_DBG_CALL_SM_TRACE, \
376                    ("STATE INSERT EVENT ")); \
377    RPC_CN_CALL_SM_TRC ((crep), (event)->event_id, (RPC_CN_PKT_CALL_ID ((rpc_cn_packet_p_t) RPC_CN_CREP_SEND_HDR (crep))));\
378    rpc__cn_sm_insert_event ((event),\
379                             &((crep)->assoc_state));\
380}
381
382#endif /* _CNCLSM_H */
383