1 /*
2 * connIbss.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /** \file connIbss.c
35 * \brief IBSS connection implementation
36 *
37 * \see connIbss.h
38 */
39
40 /***************************************************************************/
41 /* */
42 /* MODULE: connIbss.c */
43 /* PURPOSE: IBSS connection implementation */
44 /* */
45 /***************************************************************************/
46
47 #define __FILE_ID__ FILE_ID_26
48 #include "tidef.h"
49 #include "report.h"
50 #include "osApi.h"
51 #include "conn.h"
52 #include "connIbss.h"
53 #include "timer.h"
54 #include "fsm.h"
55 #include "siteMgrApi.h"
56 #include "sme.h"
57 #include "rsnApi.h"
58 #include "DataCtrl_Api.h"
59 #include "paramOut.h"
60 #include "connApi.h"
61 #include "EvHandler.h"
62 #include "currBss.h"
63 #include "TrafficMonitorAPI.h"
64 #include "healthMonitor.h"
65 #include "TWDriver.h"
66
67
68 /* Local functions prototypes */
69 /* Local functions prototypes */
70 static TI_STATUS waitDisconnToCmplt_to_idle (void *pData);
71 static TI_STATUS idle_to_selfWait(void *pData);
72
73 static TI_STATUS idle_to_rsnWait(void *pData);
74
75 static TI_STATUS selfWait_to_waitToDisconnCmplt(void *pData);
76 static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData);
77 static TI_STATUS connected_to_waitToDisconnCmplt(void *pData);
78 static TI_STATUS selfWait_to_rsnWait(void *pData);
79 static TI_STATUS rsnWait_to_connected(void *pData);
80 static TI_STATUS actionUnexpected(void *pData);
81 static TI_STATUS actionNop(void *pData);
82 static TI_STATUS selfw_merge_rsnw(void *pData);
83 static TI_STATUS rsnw_merge_rsnw(void *pData);
84 static TI_STATUS conn_merge_conn(void *pData);
85
86 /********************************************/
87 /* Functions Implementations */
88 /********************************************/
89
90 /***********************************************************************
91 * conn_ibssConfig
92 ***********************************************************************
93 DESCRIPTION: IBSS Connection configuration function, called by the conection set param function
94 in the selection phase. Configures the connection state machine to IBSS connection mode
95
96 INPUT: hConn - Connection handle.
97
98 OUTPUT:
99
100 RETURN: TI_OK on success, TI_NOK otherwise
101
102 ************************************************************************/
conn_ibssConfig(conn_t * pConn)103 TI_STATUS conn_ibssConfig(conn_t *pConn)
104 {
105
106 fsm_actionCell_t smMatrix[CONN_IBSS_NUM_STATES][CONN_IBSS_NUM_EVENTS] =
107 {
108
109 /* next state and actions for IDLE state */
110 { {STATE_CONN_IBSS_SELF_WAIT, idle_to_selfWait }, /* CONN_IBSS_CREATE */
111 {STATE_CONN_IBSS_RSN_WAIT, idle_to_rsnWait }, /* CONN_IBSS_CONNECT */
112 {STATE_CONN_IBSS_IDLE, actionNop }, /* CONN_IBSS_DISCONNECT */
113 {STATE_CONN_IBSS_IDLE, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */
114 {STATE_CONN_IBSS_IDLE, actionUnexpected }, /* CONN_IBSS_STA_JOINED */
115 {STATE_CONN_IBSS_IDLE, actionUnexpected }, /* CONN_IBSS_MERGE */
116 {STATE_CONN_IBSS_IDLE, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */
117 },
118
119 /* next state and actions for SELF_WAIT state */
120 { {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected }, /* CONN_IBSS_CREATE */
121 {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected }, /* CONN_IBSS_CONNECT */
122 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, selfWait_to_waitToDisconnCmplt }, /* CONN_IBSS_DISCONNECT */
123 {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */
124 {STATE_CONN_IBSS_RSN_WAIT, selfWait_to_rsnWait }, /* CONN_IBSS_STA_JOINED */
125 {STATE_CONN_IBSS_RSN_WAIT, selfw_merge_rsnw }, /* CONN_IBSS_MERGE */
126 {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */
127 },
128
129 /* next state and actions for RSN_WAIT state */
130 { {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected }, /* CONN_IBSS_CREATE */
131 {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected }, /* CONN_IBSS_CONNECT */
132 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, rsnWait_to_waitToDisconnCmplt }, /* CONN_IBSS_DISCONNECT */
133 {STATE_CONN_IBSS_CONNECTED, rsnWait_to_connected }, /* CONN_IBSS_RSN_SUCC */
134 {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected }, /* CONN_IBSS_STA_JOINED */
135 {STATE_CONN_IBSS_RSN_WAIT, rsnw_merge_rsnw }, /* CONN_IBSS_MERGE */
136 {STATE_CONN_IBSS_RSN_WAIT, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */
137 },
138
139 /* next state and actions for CONNECTED state */
140 { {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_CREATE */
141 {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_CONNECT */
142 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, connected_to_waitToDisconnCmplt }, /* CONN_IBSS_DISCONNECT */
143 {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */
144 {STATE_CONN_IBSS_CONNECTED, actionUnexpected }, /* CONN_IBSS_STA_JOINED */
145 {STATE_CONN_IBSS_CONNECTED, conn_merge_conn }, /* CONN_IBSS_MERGE */
146 {STATE_CONN_IBSS_CONNECTED, actionUnexpected } /* CONN_IBSS_DISCONN_COMPLETE */
147 },
148
149 /* next state and actions for STATE_CONN_IBSS_WAIT_DISCONN_CMPLT state */
150 { {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_CREATE */
151 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_CONNECT */
152 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_DISCONNECT */
153 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_RSN_SUCC */
154 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_STA_JOINED */
155 {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected }, /* CONN_IBSS_MERGE */
156 {STATE_CONN_IBSS_IDLE, waitDisconnToCmplt_to_idle } /* CONN_IBSS_DISCONN_COMPLETE */
157 }
158
159 };
160
161 return fsm_Config(pConn->ibss_pFsm, (fsm_Matrix_t)smMatrix, CONN_IBSS_NUM_STATES, CONN_IBSS_NUM_EVENTS, conn_ibssSMEvent, pConn->hOs);
162 }
163
164
165 /***********************************************************************
166 * conn_ibssSMEvent
167 ***********************************************************************
168 DESCRIPTION: IBSS Connection SM event processing function, called by the connection API
169 Perform the following:
170 - Print the state movement as a result from the event
171 - Calls the generic state machine event processing function which preform the following:
172 - Calls the correspoding callback function
173 - Move to next state
174
175 INPUT: currentState - Pointer to the connection current state.
176 event - Received event
177 pConn - Connection handle
178
179 OUTPUT:
180
181 RETURN: TI_OK on success, TI_NOK otherwise
182
183 ************************************************************************/
conn_ibssSMEvent(TI_UINT8 * currentState,TI_UINT8 event,TI_HANDLE hConn)184 TI_STATUS conn_ibssSMEvent(TI_UINT8 *currentState, TI_UINT8 event, TI_HANDLE hConn)
185 {
186 conn_t *pConn = (conn_t *)hConn;
187 TI_STATUS status;
188 TI_UINT8 nextState;
189
190 status = fsm_GetNextState(pConn->ibss_pFsm, *currentState, event, &nextState);
191 if (status != TI_OK)
192 {
193 TRACE0(pConn->hReport, REPORT_SEVERITY_SM, "IBSS State machine error, failed getting next state\n");
194 return(TI_NOK);
195 }
196
197 TRACE3( pConn->hReport, REPORT_SEVERITY_INFORMATION, "conn_ibssSMEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currentState, event, nextState);
198 status = fsm_Event(pConn->ibss_pFsm, currentState, event, (void *)pConn);
199
200 return status;
201 }
202
203
connIbss_DisconnectComplete(conn_t * pConn,TI_UINT8 * data,TI_UINT8 dataLength)204 void connIbss_DisconnectComplete (conn_t *pConn, TI_UINT8 *data, TI_UINT8 dataLength)
205 {
206 /* send an DISCONNECT COMPLETE event to the SM */
207 conn_ibssSMEvent(&pConn->state, CONN_IBSS_DISCONN_COMPLETE, (TI_HANDLE) pConn);
208 }
209
210 /************************************************************************************************************/
211 /* In the following section are listed the callback function used by the IBSS connection state machine */
212 /************************************************************************************************************/
213
214 /***********************************************************************
215 * selfWait_to_rsnWait
216 ***********************************************************************
217 DESCRIPTION:
218
219
220 INPUT:
221
222 OUTPUT:
223
224 RETURN: TI_OK on success, TI_NOK otherwise
225
226 ************************************************************************/
selfWait_to_rsnWait(void * pData)227 static TI_STATUS selfWait_to_rsnWait (void *pData)
228 {
229 conn_t *pConn = (conn_t *)pData;
230 paramInfo_t param;
231
232 tmr_StopTimer (pConn->hConnTimer);
233
234 param.paramType = RX_DATA_PORT_STATUS_PARAM;
235 param.content.rxDataPortStatus = OPEN_EAPOL;
236 rxData_setParam (pConn->hRxData, ¶m);
237
238 /* Update TxMgmtQueue SM to enable EAPOL packets. */
239 txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL);
240
241 /*
242 * Notify that the driver is associated to the supplicant\IP stack.
243 */
244 EvHandlerSendEvent (pConn->hEvHandler, IPC_EVENT_ASSOCIATED, NULL, 0);
245
246 return rsn_start (pConn->hRsn);
247 }
248
249
250 /***********************************************************************
251 * rsnWait_to_connected
252 ***********************************************************************
253 DESCRIPTION:
254
255
256 INPUT:
257
258 OUTPUT:
259
260 RETURN: TI_OK on success, TI_NOK otherwise
261
262 ************************************************************************/
rsnWait_to_connected(void * pData)263 static TI_STATUS rsnWait_to_connected(void *pData)
264 {
265 paramInfo_t param;
266
267 conn_t *pConn=(conn_t *)pData;
268
269 TrafficMonitor_Start( pConn->hTrafficMonitor );
270
271 healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_CONNECTED);
272
273 siteMgr_start(pConn->hSiteMgr);
274
275 param.paramType = RX_DATA_PORT_STATUS_PARAM;
276 param.content.rxDataPortStatus = OPEN;
277 rxData_setParam(((conn_t *)pData)->hRxData, ¶m);
278
279 /* Update TxMgmtQueue SM to open Tx path to all packets. */
280 txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_OPEN);
281
282 /* Update current BSS connection type and mode */
283 currBSS_updateConnectedState(pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
284
285 sme_ReportConnStatus(((conn_t *)pData)->hSmeSm, STATUS_SUCCESSFUL, 0);
286
287 return TI_OK;
288 }
289
selfw_merge_rsnw(void * pData)290 static TI_STATUS selfw_merge_rsnw(void *pData)
291 {
292 conn_t *pConn=(conn_t *)pData;
293 paramInfo_t param;
294
295 os_printf("IBSS selfw_merge_rsnw!!!!!!!!!!\n");
296
297 tmr_StopTimer (pConn->hConnTimer);
298 siteMgr_join(pConn->hSiteMgr);
299
300 param.paramType = RX_DATA_PORT_STATUS_PARAM;
301 param.content.rxDataPortStatus = OPEN_EAPOL;
302 rxData_setParam (pConn->hRxData, ¶m);
303
304 /* Update TxMgmtQueue SM to enable EAPOL packets. */
305 txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL);
306
307 /*
308 * Notify that the driver is associated to the supplicant\IP stack.
309 */
310 EvHandlerSendEvent (pConn->hEvHandler, IPC_EVENT_ASSOCIATED, NULL, 0);
311
312 return rsn_start (pConn->hRsn);
313
314 }
315
316
rsnw_merge_rsnw(void * pData)317 static TI_STATUS rsnw_merge_rsnw(void *pData)
318 {
319 conn_t *pConn=(conn_t *)pData;
320
321 os_printf("IBSS rsnw_merge_rsnw!!!!!!!!!!\n");
322
323 siteMgr_join(pConn->hSiteMgr);
324
325 return TI_OK;
326 }
327
328
conn_merge_conn(void * pData)329 static TI_STATUS conn_merge_conn(void *pData)
330 {
331 conn_t *pConn=(conn_t *)pData;
332
333 os_printf("IBSS conn_merge_conn!!!!!!!!!!\n");
334
335 siteMgr_join(pConn->hSiteMgr);
336
337 return TI_OK;
338 }
339
waitDisconnToCmplt_to_idle(void * pData)340 static TI_STATUS waitDisconnToCmplt_to_idle (void *pData)
341 {
342 conn_t *pConn = (conn_t *)pData;
343
344 /* Inform the SME about the connection lost */
345 /* we use this status at SME, if != 0 means that assoc frame sent */
346 sme_ReportConnStatus(pConn->hSmeSm, STATUS_UNSPECIFIED, 1);
347 return TI_OK;
348 }
349
350
351
352 /***********************************************************************
353 * actionUnexpected
354 ***********************************************************************
355 DESCRIPTION:
356
357
358 INPUT:
359
360 OUTPUT:
361
362 RETURN: TI_OK on success, TI_NOK otherwise
363
364 ************************************************************************/
actionUnexpected(void * pData)365 static TI_STATUS actionUnexpected(void *pData)
366 {
367 #ifdef TI_DBG
368 conn_t *pConn = (conn_t *)pData;
369
370 TRACE0(pConn->hReport, REPORT_SEVERITY_SM, "State machine error, unexpected Event\n\n");
371 #endif /*TI_DBG*/
372
373 return TI_OK;
374 }
375
376 /***********************************************************************
377 * actionNop
378 ***********************************************************************
379 DESCRIPTION:
380
381
382 INPUT:
383
384 OUTPUT:
385
386 RETURN: TI_OK on success, TI_NOK otherwise
387
388 ************************************************************************/
actionNop(void * pData)389 static TI_STATUS actionNop(void *pData)
390 {
391 return TI_OK;
392 }
393
394
395 /***********************************************************************
396 * selfWait_to_waitToDisconnCmplt
397 ***********************************************************************
398 DESCRIPTION:
399
400
401 INPUT:
402
403 OUTPUT:
404
405 RETURN: TI_OK on success, TI_NOK otherwise
406
407 ************************************************************************/
selfWait_to_waitToDisconnCmplt(void * pData)408 static TI_STATUS selfWait_to_waitToDisconnCmplt (void *pData)
409 {
410 conn_t *pConn = (conn_t *)pData;
411 paramInfo_t param;
412
413 tmr_StopTimer (pConn->hConnTimer);
414
415 siteMgr_removeSelfSite(pConn->hSiteMgr);
416
417 /* Update current BSS connection type and mode */
418 currBSS_updateConnectedState(pConn->hCurrBss, TI_FALSE, BSS_INDEPENDENT);
419
420 /* stop beacon generation */
421 param.paramType = RX_DATA_PORT_STATUS_PARAM;
422 param.content.rxDataPortStatus = CLOSE;
423 rxData_setParam(pConn->hRxData, ¶m);
424
425 /* Update TxMgmtQueue SM to close Tx path. */
426 txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_CLOSE);
427
428 TWD_CmdFwDisconnect (pConn->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED);
429
430 return TI_OK;
431 }
432
433
434
435 /***********************************************************************
436 * rsnWait_to_waitToDisconnCmplt
437 ***********************************************************************
438 DESCRIPTION:
439
440
441 INPUT:
442
443 OUTPUT:
444
445 RETURN: TI_OK on success, TI_NOK otherwise
446
447 ************************************************************************/
rsnWait_to_waitToDisconnCmplt(void * pData)448 static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData)
449 {
450 paramInfo_t param;
451 TI_STATUS tStatus;
452
453 tStatus = rsn_stop(((conn_t *)pData)->hRsn, TI_FALSE);
454
455 param.paramType = RX_DATA_PORT_STATUS_PARAM;
456 param.content.rxDataPortStatus = CLOSE;
457 rxData_setParam(((conn_t *)pData)->hRxData, ¶m);
458
459 /* Update TxMgmtQueue SM to close Tx path. */
460 txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_CLOSE);
461
462 /* Update current BSS connection type and mode */
463 currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_FALSE, BSS_INDEPENDENT);
464
465 /* Stop beacon generation */
466 TWD_CmdFwDisconnect (((conn_t *)pData)->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED);
467
468 return tStatus;
469 }
470
471
472 /***********************************************************************
473 * connected_to_waitToDisconnCmplt
474 ***********************************************************************
475 DESCRIPTION:
476
477
478 INPUT:
479
480 OUTPUT:
481
482 RETURN: TI_OK on success, TI_NOK otherwise
483
484 ************************************************************************/
connected_to_waitToDisconnCmplt(void * pData)485 static TI_STATUS connected_to_waitToDisconnCmplt(void *pData)
486 {
487 conn_t *pConn=(conn_t *)pData;
488
489 TrafficMonitor_Stop(pConn->hTrafficMonitor);
490
491 healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_DISCONNECTED);
492
493 /* The logic of this action is identical to rsnWait_to_idle */
494 return rsnWait_to_waitToDisconnCmplt(pConn);
495 }
496
497
498
499
500
501 /***********************************************************************
502 * idle_to_selfWait
503 ***********************************************************************
504 DESCRIPTION:
505
506
507 INPUT:
508
509 OUTPUT:
510
511 RETURN: TI_OK on success, TI_NOK otherwise
512
513 ************************************************************************/
idle_to_selfWait(void * pData)514 static TI_STATUS idle_to_selfWait (void *pData)
515 {
516 conn_t *pConn = (conn_t *)pData;
517 TI_UINT16 randomTime;
518
519 siteMgr_join (pConn->hSiteMgr);
520
521 /* get a randomTime that is constructed of the lower 13 bits ot the system time to
522 get a MS random time of ~8000 ms */
523 randomTime = os_timeStampMs (pConn->hOs) & 0x1FFF;
524
525 /* Update current BSS connection type and mode */
526 currBSS_updateConnectedState (pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
527
528 tmr_StartTimer (pConn->hConnTimer,
529 conn_timeout,
530 (TI_HANDLE)pConn,
531 pConn->timeout + randomTime,
532 TI_FALSE);
533
534 return TI_OK;
535 }
536
537
538
539 /***********************************************************************
540 * idle_to_rsnWait
541 ***********************************************************************
542 DESCRIPTION:
543
544
545 INPUT:
546
547 OUTPUT:
548
549 RETURN: TI_OK on success, TI_NOK otherwise
550
551 ************************************************************************/
idle_to_rsnWait(void * pData)552 static TI_STATUS idle_to_rsnWait(void *pData)
553 {
554 paramInfo_t param;
555
556 siteMgr_join(((conn_t *)pData)->hSiteMgr);
557
558 param.paramType = RX_DATA_PORT_STATUS_PARAM;
559 param.content.rxDataPortStatus = OPEN_EAPOL;
560 rxData_setParam(((conn_t *)pData)->hRxData, ¶m);
561
562 /* Update TxMgmtQueue SM to enable EAPOL packets. */
563 txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_EAPOL);
564
565 /*
566 * Notify that the driver is associated to the supplicant\IP stack.
567 */
568 EvHandlerSendEvent(((conn_t *)pData)->hEvHandler, IPC_EVENT_ASSOCIATED, NULL,0);
569
570 /* Update current BSS connection type and mode */
571 currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
572
573 return rsn_start(((conn_t *)pData)->hRsn);
574 }
575
576