David Fletcher
/
cc3100_Test_Demo
TI's CC3100. A test demo with very little testing done!
Embed:
(wiki syntax)
Show/hide line numbers
fPtr_func.cpp
00001 /* 00002 * - CC31xx/CC32xx Host Driver Implementation 00003 * 00004 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 00005 * 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. 00018 * 00019 * Neither the name of Texas Instruments Incorporated nor the names of 00020 * its contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00027 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 */ 00036 00037 #include "cc3100_simplelink.h" 00038 00039 #include "cc3100.h" 00040 #include "cc3100_driver.h" 00041 #include "fPtr_func.h" 00042 00043 00044 using namespace mbed_cc3100; 00045 00046 cc3100 *_cc3100_; 00047 00048 #ifdef __cplusplus 00049 extern "C" { 00050 #endif 00051 00052 /* General Events handling*/ 00053 #if defined (EXT_LIB_REGISTERED_GENERAL_EVENTS) 00054 00055 typedef _SlEventPropogationStatus_e (*general_callback) (SlDeviceEvent_t *); 00056 00057 static const general_callback general_callbacks[] = 00058 { 00059 #ifdef SlExtLib1GeneralEventHandler 00060 SlExtLib1GeneralEventHandler, 00061 #endif 00062 00063 #ifdef SlExtLib2GeneralEventHandler 00064 SlExtLib2GeneralEventHandler, 00065 #endif 00066 00067 #ifdef SlExtLib3GeneralEventHandler 00068 SlExtLib3GeneralEventHandler, 00069 #endif 00070 00071 #ifdef SlExtLib4GeneralEventHandler 00072 SlExtLib4GeneralEventHandler, 00073 #endif 00074 00075 #ifdef SlExtLib5GeneralEventHandler 00076 SlExtLib5GeneralEventHandler, 00077 #endif 00078 }; 00079 00080 #undef _SlDrvHandleGeneralEvents 00081 00082 /******************************************************************** 00083 _SlDrvHandleGeneralEvents 00084 Iterates through all the general(device) event handlers which are 00085 registered by the external libs/user application. 00086 *********************************************************************/ 00087 void _SlDrvHandleGeneralEvents(SlDeviceEvent_t *slGeneralEvent) 00088 { 00089 uint8_t i; 00090 00091 /* Iterate over all the extenal libs handlers */ 00092 for ( i = 0 ; i < sizeof(general_callbacks)/sizeof(general_callbacks[0]) ; i++ ) 00093 { 00094 if (EVENT_PROPAGATION_BLOCK == general_callbacks[i](slGeneralEvent) ) 00095 { 00096 /* exit immediately and do not call the user specific handler as well */ 00097 return; 00098 } 00099 } 00100 00101 /* At last call the Application specific handler if registered */ 00102 #ifdef sl_GeneralEvtHdlr 00103 sl_GeneralEvtHdlr(slGeneralEvent); 00104 #endif 00105 00106 } 00107 #endif 00108 00109 00110 00111 /* WLAN Events handling*/ 00112 00113 #if defined (EXT_LIB_REGISTERED_WLAN_EVENTS) 00114 00115 typedef _SlEventPropogationStatus_e (*wlan_callback) (SlWlanEvent_t *); 00116 00117 static wlan_callback wlan_callbacks[] = 00118 { 00119 #ifdef SlExtLib1WlanEventHandler 00120 SlExtLib1WlanEventHandler, 00121 #endif 00122 00123 #ifdef SlExtLib2WlanEventHandler 00124 SlExtLib2WlanEventHandler, 00125 #endif 00126 00127 #ifdef SlExtLib3WlanEventHandler 00128 SlExtLib3WlanEventHandler, 00129 #endif 00130 00131 #ifdef SlExtLib4WlanEventHandler 00132 SlExtLib4WlanEventHandler, 00133 #endif 00134 00135 #ifdef SlExtLib5WlanEventHandler 00136 SlExtLib5WlanEventHandler, 00137 #endif 00138 }; 00139 00140 #undef _SlDrvHandleWlanEvents 00141 00142 /*********************************************************** 00143 _SlDrvHandleWlanEvents 00144 Iterates through all the wlan event handlers which are 00145 registered by the external libs/user application. 00146 ************************************************************/ 00147 void _SlDrvHandleWlanEvents(SlWlanEvent_t *slWlanEvent) 00148 { 00149 uint8_t i; 00150 00151 /* Iterate over all the extenal libs handlers */ 00152 for ( i = 0 ; i < sizeof(wlan_callbacks)/sizeof(wlan_callbacks[0]) ; i++ ) 00153 { 00154 if ( EVENT_PROPAGATION_BLOCK == wlan_callbacks[i](slWlanEvent) ) 00155 { 00156 /* exit immediately and do not call the user specific handler as well */ 00157 return; 00158 } 00159 } 00160 00161 /* At last call the Application specific handler if registered */ 00162 #ifdef sl_WlanEvtHdlr 00163 sl_WlanEvtHdlr(slWlanEvent); 00164 #endif 00165 00166 } 00167 #endif 00168 00169 00170 /* NetApp Events handling */ 00171 #if defined (EXT_LIB_REGISTERED_NETAPP_EVENTS) 00172 00173 typedef _SlEventPropogationStatus_e (*netApp_callback) (SlNetAppEvent_t *); 00174 00175 static const netApp_callback netApp_callbacks[] = 00176 { 00177 #ifdef SlExtLib1NetAppEventHandler 00178 SlExtLib1NetAppEventHandler, 00179 #endif 00180 00181 #ifdef SlExtLib2NetAppEventHandler 00182 SlExtLib2NetAppEventHandler, 00183 #endif 00184 00185 #ifdef SlExtLib3NetAppEventHandler 00186 SlExtLib3NetAppEventHandler, 00187 #endif 00188 00189 #ifdef SlExtLib4NetAppEventHandler 00190 SlExtLib4NetAppEventHandler, 00191 #endif 00192 00193 #ifdef SlExtLib5NetAppEventHandler 00194 SlExtLib5NetAppEventHandler, 00195 #endif 00196 }; 00197 00198 #undef _SlDrvHandleNetAppEvents 00199 00200 /************************************************************ 00201 _SlDrvHandleNetAppEvents 00202 Iterates through all the net app event handlers which are 00203 registered by the external libs/user application. 00204 ************************************************************/ 00205 void _SlDrvHandleNetAppEvents(SlNetAppEvent_t *slNetAppEvent) 00206 { 00207 uint8_t i; 00208 00209 /* Iterate over all the extenal libs handlers */ 00210 for ( i = 0 ; i < sizeof(netApp_callbacks)/sizeof(netApp_callbacks[0]) ; i++ ) 00211 { 00212 if (EVENT_PROPAGATION_BLOCK == netApp_callbacks[i](slNetAppEvent) ) 00213 { 00214 /* exit immediately and do not call the user specific handler as well */ 00215 return; 00216 } 00217 } 00218 00219 /* At last call the Application specific handler if registered */ 00220 #ifdef sl_NetAppEvtHdlr 00221 sl_NetAppEvtHdlr(slNetAppEvent); 00222 #endif 00223 00224 } 00225 #endif 00226 00227 00228 /* Http Server Events handling */ 00229 #if defined (EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) 00230 00231 typedef _SlEventPropogationStatus_e (*httpServer_callback) (SlHttpServerEvent_t*, SlHttpServerResponse_t*); 00232 00233 static const httpServer_callback httpServer_callbacks[] = 00234 { 00235 #ifdef SlExtLib1HttpServerEventHandler 00236 SlExtLib1HttpServerEventHandler, 00237 #endif 00238 00239 #ifdef SlExtLib2HttpServerEventHandler 00240 SlExtLib2HttpServerEventHandler, 00241 #endif 00242 00243 #ifdef SlExtLib3HttpServerEventHandler 00244 SlExtLib3HttpServerEventHandler, 00245 #endif 00246 00247 #ifdef SlExtLib4HttpServerEventHandler 00248 SlExtLib4HttpServerEventHandler, 00249 #endif 00250 00251 #ifdef SlExtLib5HttpServerEventHandler 00252 SlExtLib5HttpServerEventHandler, 00253 #endif 00254 }; 00255 00256 #undef _SlDrvHandleHttpServerEvents 00257 00258 /******************************************************************* 00259 _SlDrvHandleHttpServerEvents 00260 Iterates through all the http server event handlers which are 00261 registered by the external libs/user application. 00262 ********************************************************************/ 00263 void _SlDrvHandleHttpServerEvents(SlHttpServerEvent_t *slHttpServerEvent, SlHttpServerResponse_t *slHttpServerResponse) 00264 { 00265 _u8 i; 00266 00267 /* Iterate over all the external libs handlers */ 00268 for ( i = 0 ; i < sizeof(httpServer_callbacks)/sizeof(httpServer_callbacks[0]) ; i++ ) 00269 { 00270 if ( EVENT_PROPAGATION_BLOCK == httpServer_callbacks[i](slHttpServerEvent, slHttpServerResponse) ) 00271 { 00272 /* exit immediately and do not call the user specific handler as well */ 00273 return; 00274 } 00275 } 00276 00277 /* At last call the Application specific handler if registered */ 00278 #ifdef sl_HttpServerCallback 00279 sl_HttpServerCallback(slHttpServerEvent, slHttpServerResponse); 00280 #endif 00281 00282 } 00283 #endif 00284 00285 00286 /* Socket Events */ 00287 #if defined (EXT_LIB_REGISTERED_SOCK_EVENTS) 00288 00289 typedef _SlEventPropogationStatus_e (*sock_callback) (SlSockEvent_t *); 00290 00291 static const sock_callback sock_callbacks[] = 00292 { 00293 #ifdef SlExtLib1SockEventHandler 00294 SlExtLib1SockEventHandler, 00295 #endif 00296 00297 #ifdef SlExtLib2SockEventHandler 00298 SlExtLib2SockEventHandler, 00299 #endif 00300 00301 #ifdef SlExtLib3SockEventHandler 00302 SlExtLib3SockEventHandler, 00303 #endif 00304 00305 #ifdef SlExtLib4SockEventHandler 00306 SlExtLib4SockEventHandler, 00307 #endif 00308 00309 #ifdef SlExtLib5SockEventHandler 00310 SlExtLib5SockEventHandler, 00311 #endif 00312 }; 00313 00314 /************************************************************* 00315 _SlDrvHandleSockEvents 00316 Iterates through all the socket event handlers which are 00317 registered by the external libs/user application. 00318 **************************************************************/ 00319 void _SlDrvHandleSockEvents(SlSockEvent_t *slSockEvent) 00320 { 00321 uint8_t i; 00322 00323 /* Iterate over all the external libs handlers */ 00324 for ( i = 0 ; i < sizeof(sock_callbacks)/sizeof(sock_callbacks[0]) ; i++ ) 00325 { 00326 if ( EVENT_PROPAGATION_BLOCK == sock_callbacks[i](slSockEvent) ) 00327 { 00328 /* exit immediately and do not call the user specific handler as well */ 00329 return; 00330 } 00331 } 00332 00333 /* At last call the Application specific handler if registered */ 00334 #ifdef sl_SockEvtHdlr 00335 sl_SockEvtHdlr(slSockEvent); 00336 #endif 00337 00338 } 00339 00340 #endif 00341 00342 /*! 00343 \brief This function handles ping report events 00344 00345 \param[in] pPingReport holds the ping report statistics 00346 00347 \return None 00348 00349 \note 00350 00351 \warning 00352 */ 00353 void SimpleLinkPingReport(SlPingReport_t *pPingReport) 00354 { 00355 _cc3100_->SET_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE); 00356 00357 if(pPingReport == NULL) 00358 printf(" [PING REPORT] NULL Pointer Error\r\n"); 00359 00360 g_PingPacketsRecv = pPingReport->PacketsReceived; 00361 } 00362 00363 00364 /*******************************************************************************/ 00365 /* _sl_HandleAsync_Accept */ 00366 /*******************************************************************************/ 00367 #ifndef SL_TINY_EXT 00368 void _sl_HandleAsync_Accept(void *pVoidBuf) 00369 { 00370 _SocketAddrResponse_u *pMsgArgs = (_SocketAddrResponse_u *)_SL_RESP_ARGS_START(pVoidBuf); 00371 00372 _cc3100_->_driver._SlDrvProtectionObjLockWaitForever(); 00373 00374 VERIFY_PROTOCOL(( pMsgArgs->IpV4.sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); 00375 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00376 00377 memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs,sizeof(_SocketAddrResponse_u)); 00378 _cc3100_->_driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00379 00380 _cc3100_->_driver._SlDrvProtectionObjUnLock(); 00381 return; 00382 } 00383 00384 /*******************************************************************************/ 00385 /* _sl_HandleAsync_Connect */ 00386 /*******************************************************************************/ 00387 void _sl_HandleAsync_Connect(void *pVoidBuf) 00388 { 00389 _SocketResponse_t *pMsgArgs = (_SocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00390 00391 _cc3100_->_driver._SlDrvProtectionObjLockWaitForever(); 00392 00393 VERIFY_PROTOCOL((pMsgArgs->sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS); 00394 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00395 00396 ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->sd = pMsgArgs->sd; 00397 ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->statusOrLen = pMsgArgs->statusOrLen; 00398 00399 _cc3100_->_driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00400 _cc3100_->_driver._SlDrvProtectionObjUnLock(); 00401 return; 00402 } 00403 00404 /*******************************************************************************/ 00405 /* _sl_HandleAsync_Select */ 00406 /*******************************************************************************/ 00407 void _sl_HandleAsync_Select(void *pVoidBuf) 00408 { 00409 _SelectAsyncResponse_t *pMsgArgs = (_SelectAsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00410 00411 _cc3100_->_driver._SlDrvProtectionObjLockWaitForever(); 00412 00413 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00414 00415 memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_SelectAsyncResponse_t)); 00416 00417 _cc3100_->_driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00418 _cc3100_->_driver._SlDrvProtectionObjUnLock(); 00419 00420 return; 00421 } 00422 00423 #endif 00424 00425 /******************************************************************************/ 00426 /* _sl_HandleAsync_DnsGetHostByName */ 00427 /******************************************************************************/ 00428 void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf) 00429 { 00430 _GetHostByNameIPv4AsyncResponse_t *pMsgArgs = (_GetHostByNameIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00431 00432 _cc3100_->_driver._SlDrvProtectionObjLockWaitForever(); 00433 00434 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00435 00436 /*IPv6 */ 00437 if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) { 00438 memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv6AsyncResponse_t)); 00439 } 00440 /*IPv4 */ 00441 else 00442 { 00443 memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv4AsyncResponse_t)); 00444 } 00445 00446 _cc3100_->_driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00447 _cc3100_->_driver._SlDrvProtectionObjUnLock(); 00448 00449 return; 00450 } 00451 00452 /******************************************************************************/ 00453 00454 /****************************************************************************** 00455 _sl_HandleAsync_DnsGetHostByService 00456 00457 CALLER NWP - Async event on sl_DnsGetHostByService with IPv4 Family 00458 00459 00460 DESCRIPTION: 00461 00462 Async event on sl_DnsGetHostByService command with IPv4 Family. 00463 Return service attributes like IP address, port and text according to service name. 00464 The user sets a service name Full/Part (see example below), and should get the: 00465 1. IP of the service 00466 2. The port of service. 00467 3. The text of service. 00468 00469 Hence it can make a connection to the specific service and use it. 00470 It is similar to get host by name method. 00471 00472 It is done by a single shot query with PTR type on the service name. 00473 00474 00475 00476 Note: 00477 1. The return's attributes are belonged to first service that is found. 00478 It can be other services with the same service name will response to 00479 the query. The results of these responses are saved in the peer cache of the NWP, and 00480 should be read by another API. 00481 00482 00483 PARAMETERS: 00484 00485 pVoidBuf - is point to opcode of the event. 00486 it contains the outputs that are given to the user 00487 00488 outputs description: 00489 00490 1.out_pAddr[] - output: Contain the IP address of the service. 00491 2.out_pPort - output: Contain the port of the service. 00492 3.inout_TextLen - Input: Contain the max length of the text that the user wants to get. 00493 it means that if the test of service is bigger that its value than 00494 the text is cut to inout_TextLen value. 00495 Output: Contain the length of the text that is returned. Can be full text or part 00496 of the text (see above). 00497 00498 4.out_pText - Contain the text of the service (full or part see above- inout_TextLen description). 00499 00500 * 00501 00502 00503 RETURNS: success or fail. 00504 00505 ******************************************************************************/ 00506 #ifndef SL_TINY_EXT 00507 void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf) 00508 { 00509 _GetHostByServiceAsyncResponse_t* Res; 00510 uint16_t TextLen; 00511 uint16_t UserTextLen; 00512 00513 /*pVoidBuf - is point to opcode of the event.*/ 00514 00515 /*set pMsgArgs to point to the attribute of the event.*/ 00516 _GetHostByServiceIPv4AsyncResponse_t *pMsgArgs = (_GetHostByServiceIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00517 00518 VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs); 00519 00520 /*IPv6*/ 00521 if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) { 00522 return; 00523 } 00524 /*IPv4*/ 00525 else { 00526 /************************************************************************************************* 00527 00528 1. Copy the attribute part of the evnt to the attribute part of the response 00529 memcpy(g_pCB->GetHostByServiceCB.pAsyncRsp, pMsgArgs, sizeof(_GetHostByServiceIPv4AsyncResponse_t)); 00530 00531 set to TextLen the text length of the service.*/ 00532 TextLen = pMsgArgs->TextLen; 00533 00534 /*Res pointed to mDNS global object struct */ 00535 Res = (_GetHostByServiceAsyncResponse_t*)g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs; 00536 00537 00538 00539 /*It is 4 bytes so we avoid from memcpy*/ 00540 Res->out_pAddr[0] = pMsgArgs->Address; 00541 Res->out_pPort[0] = pMsgArgs->Port; 00542 Res->Status = pMsgArgs->Status; 00543 00544 /*set to TextLen the text length of the user (input fromthe user).*/ 00545 UserTextLen = Res->inout_TextLen[0]; 00546 00547 /*Cut the service text if the user requested for smaller text.*/ 00548 UserTextLen = (TextLen <= UserTextLen) ? TextLen : UserTextLen; 00549 Res->inout_TextLen[0] = UserTextLen ; 00550 00551 /************************************************************************************************** 00552 00553 2. Copy the payload part of the evnt (the text) to the payload part of the response 00554 the lenght of the copy is according to the text length in the attribute part. */ 00555 00556 00557 memcpy(Res->out_pText , 00558 (int8_t *)(& pMsgArgs[1]), /* & pMsgArgs[1] -> 1st byte after the fixed header = 1st byte of variable text.*/ 00559 UserTextLen); 00560 00561 00562 /**************************************************************************************************/ 00563 _cc3100_->_driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00564 return; 00565 } 00566 } 00567 #endif 00568 00569 /*****************************************************************************/ 00570 /* _sl_HandleAsync_PingResponse */ 00571 /*****************************************************************************/ 00572 #ifndef SL_TINY_EXT 00573 void _sl_HandleAsync_PingResponse(void *pVoidBuf) 00574 { 00575 _PingReportResponse_t *pMsgArgs = (_PingReportResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00576 SlPingReport_t pingReport; 00577 00578 if(pPingCallBackFunc) { 00579 _cc3100_->_netapp.CopyPingResultsToReport(pMsgArgs,&pingReport); 00580 pPingCallBackFunc(&pingReport); 00581 } else { 00582 00583 _cc3100_->_driver._SlDrvProtectionObjLockWaitForever(); 00584 VERIFY_SOCKET_CB(NULL != g_pCB->PingCB.PingAsync.pAsyncRsp); 00585 00586 if (NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs) { 00587 memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_PingReportResponse_t)); 00588 _cc3100_->_driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00589 } 00590 _cc3100_->_driver._SlDrvProtectionObjUnLock(); 00591 } 00592 return; 00593 } 00594 #endif 00595 00596 /* ******************************************************************************/ 00597 /* _SlDrvMsgReadSpawnCtx */ 00598 /* ******************************************************************************/ 00599 _SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue) 00600 { 00601 00602 #ifdef SL_POLLING_MODE_USED 00603 int16_t retCode = OSI_OK; 00604 /* for polling based systems */ 00605 do { 00606 retCode = sl_LockObjLock(&g_pCB->GlobalLockObj, 0); 00607 if ( OSI_OK != retCode ) { 00608 if (TRUE == g_pCB->IsCmdRespWaited) { 00609 OSI_RET_OK_CHECK( sl_SyncObjSignal(&g_pCB->CmdSyncObj) ); 00610 return SL_RET_CODE_OK; 00611 } 00612 } 00613 00614 } while (OSI_OK != retCode); 00615 00616 #else 00617 00618 OSI_RET_OK_CHECK(_cc3100_->_nonos.sl_LockObjLock(&g_pCB->GlobalLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE, NON_OS_LOCK_OBJ_LOCK_VALUE, SL_OS_WAIT_FOREVER) ); 00619 00620 #endif 00621 00622 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;/* buffer must be allocated by _SlDrvMsgRead */ 00623 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; 00624 g_pCB->FunctionParams.AsyncExt.RxMsgClass = CMD_RESP_CLASS;/* init to illegal value and verify it's overwritten with the valid one */ 00625 00626 /* Messages might have been read by CmdResp context. Therefore after */ 00627 /* getting LockObj, check again where the Pending Rx Msg is still present. */ 00628 if(FALSE == (_cc3100_->_driver._SL_PENDING_RX_MSG(g_pCB))) { 00629 OSI_RET_OK_CHECK(_cc3100_->_nonos.sl_LockObjUnlock(&g_pCB->GlobalLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE)); 00630 return SL_RET_CODE_OK; 00631 } 00632 00633 VERIFY_RET_OK(_cc3100_->_driver._SlDrvMsgRead()); 00634 00635 g_pCB->RxDoneCnt++; 00636 00637 switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) { 00638 case ASYNC_EVT_CLASS: 00639 /* If got here and protected by LockObj a message is waiting */ 00640 /* to be read */ 00641 VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00642 00643 _cc3100_->_driver._SlAsyncEventGenericHandler(); 00644 00645 #if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC) 00646 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 00647 #else 00648 free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00649 #endif 00650 break; 00651 case DUMMY_MSG_CLASS: 00652 case RECV_RESP_CLASS: 00653 /* These types are legal in this context. Do nothing */ 00654 break; 00655 case CMD_RESP_CLASS: 00656 /* Command response is illegal in this context. */ 00657 /* No 'break' here: Assert! */ 00658 default: 00659 VERIFY_PROTOCOL(0); 00660 } 00661 00662 OSI_RET_OK_CHECK(_cc3100_->_nonos.sl_LockObjUnlock(&g_pCB->GlobalLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE)); 00663 00664 return(SL_RET_CODE_OK); 00665 00666 } 00667 00668 /*************************************************************************** 00669 _sl_HandleAsync_Stop - handles stop signalling to 00670 a waiting object 00671 ****************************************************************************/ 00672 void _sl_HandleAsync_Stop(void *pVoidBuf) 00673 { 00674 _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); 00675 00676 VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp); 00677 00678 _cc3100_->_driver._SlDrvProtectionObjLockWaitForever(); 00679 00680 memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t)); 00681 _cc3100_->_driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00682 _cc3100_->_driver._SlDrvProtectionObjUnLock(); 00683 return; 00684 } 00685 00686 /****************************************************************************** 00687 _SlDrvDeviceEventHandler - handles internally device async events 00688 ******************************************************************************/ 00689 void _SlDrvDeviceEventHandler(void *pArgs) 00690 { 00691 _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs; 00692 00693 switch(pHdr->GenHeader.Opcode) { 00694 case SL_OPCODE_DEVICE_INITCOMPLETE: 00695 _cc3100_->_sl_HandleAsync_InitComplete(pHdr); 00696 00697 break; 00698 case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE: 00699 _sl_HandleAsync_Stop(pHdr); 00700 00701 break; 00702 00703 00704 case SL_OPCODE_DEVICE_ABORT: 00705 { 00706 #if defined (sl_GeneralEvtHdlr) || defined(EXT_LIB_REGISTERED_GENERAL_EVENTS) 00707 SlDeviceEvent_t devHandler; 00708 devHandler.Event = SL_DEVICE_ABORT_ERROR_EVENT; 00709 devHandler.EventData.deviceReport.AbortType = *((uint32_t*)pArgs + 2); 00710 devHandler.EventData.deviceReport.AbortData = *((uint32_t*)pArgs + 3); 00711 _SlDrvHandleGeneralEvents(&devHandler); 00712 #endif 00713 } 00714 break; 00715 case SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR: 00716 #if defined (sl_GeneralEvtHdlr) || defined(EXT_LIB_REGISTERED_GENERAL_EVENTS) 00717 { 00718 _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr); 00719 SlDeviceEvent_t devHandler; 00720 devHandler.Event = SL_DEVICE_FATAL_ERROR_EVENT; 00721 devHandler.EventData.deviceEvent.status = pMsgArgs->status & 0xFF; 00722 devHandler.EventData.deviceEvent.sender = (SlErrorSender_e)((pMsgArgs->status >> 8) & 0xFF); 00723 _SlDrvHandleGeneralEvents(&devHandler); 00724 } 00725 #endif 00726 break; 00727 default: 00728 //SL_ERROR_TRACE2(MSG_306, "ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x = %i", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode); 00729 printf("ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x = %i", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode); 00730 00731 } 00732 } 00733 00734 /*****************************************************************************/ 00735 /* _SlDrvNetAppEventHandler */ 00736 /*****************************************************************************/ 00737 void _SlDrvNetAppEventHandler(void *pArgs) 00738 { 00739 _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs; 00740 #if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) 00741 SlHttpServerEvent_t httpServerEvent; 00742 SlHttpServerResponse_t httpServerResponse; 00743 #endif 00744 switch(pHdr->GenHeader.Opcode) { 00745 case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE: 00746 case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE_V6: 00747 _sl_HandleAsync_DnsGetHostByName(pArgs); 00748 break; 00749 #ifndef SL_TINY_EXT 00750 case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE: 00751 case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE_V6: 00752 _sl_HandleAsync_DnsGetHostByService(pArgs); 00753 break; 00754 case SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE: 00755 _sl_HandleAsync_PingResponse(pArgs); 00756 break; 00757 #endif 00758 00759 #if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS) 00760 case SL_OPCODE_NETAPP_HTTPGETTOKENVALUE: { 00761 00762 uint8_t *pTokenName; 00763 slHttpServerData_t Token_value; 00764 sl_NetAppHttpServerGetToken_t *httpGetToken = (sl_NetAppHttpServerGetToken_t *)_SL_RESP_ARGS_START(pHdr); 00765 pTokenName = (uint8_t *)((sl_NetAppHttpServerGetToken_t *)httpGetToken + 1); 00766 00767 httpServerResponse.Response = SL_NETAPP_HTTPSETTOKENVALUE; 00768 httpServerResponse.ResponseData.token_value.len = MAX_TOKEN_VALUE_LEN; 00769 00770 /* Reuse the async buffer for getting the token value response from the user */ 00771 httpServerResponse.ResponseData.token_value.data = (uint8_t *)_SL_RESP_ARGS_START(pHdr) + MAX_TOKEN_NAME_LEN; 00772 httpServerEvent.Event = SL_NETAPP_HTTPGETTOKENVALUE_EVENT; 00773 00774 httpServerEvent.EventData.httpTokenName.len = httpGetToken->token_name_len; 00775 httpServerEvent.EventData.httpTokenName.data = pTokenName; 00776 00777 Token_value.token_name = pTokenName; 00778 00779 _SlDrvHandleHttpServerEvents (&httpServerEvent, &httpServerResponse); 00780 00781 Token_value.value_len = httpServerResponse.ResponseData.token_value.len; 00782 Token_value.name_len = httpServerEvent.EventData.httpTokenName.len; 00783 00784 Token_value.token_value = httpServerResponse.ResponseData.token_value.data; 00785 00786 00787 _cc3100_->_netapp.sl_NetAppSendTokenValue(&Token_value); 00788 #endif 00789 } 00790 break; 00791 00792 case SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE: { 00793 #ifdef sl_HttpServerCallback 00794 uint8_t *pPostParams; 00795 00796 sl_NetAppHttpServerPostToken_t *httpPostTokenArgs = (sl_NetAppHttpServerPostToken_t *)_SL_RESP_ARGS_START(pHdr); 00797 pPostParams = (uint8_t *)((sl_NetAppHttpServerPostToken_t *)httpPostTokenArgs + 1); 00798 00799 httpServerEvent.Event = SL_NETAPP_HTTPPOSTTOKENVALUE_EVENT; 00800 00801 httpServerEvent.EventData.httpPostData.action.len = httpPostTokenArgs->post_action_len; 00802 httpServerEvent.EventData.httpPostData.action.data = pPostParams; 00803 pPostParams+=httpPostTokenArgs->post_action_len; 00804 00805 httpServerEvent.EventData.httpPostData.token_name.len = httpPostTokenArgs->token_name_len; 00806 httpServerEvent.EventData.httpPostData.token_name.data = pPostParams; 00807 pPostParams+=httpPostTokenArgs->token_name_len; 00808 00809 httpServerEvent.EventData.httpPostData.token_value.len = httpPostTokenArgs->token_value_len; 00810 httpServerEvent.EventData.httpPostData.token_value.data = pPostParams; 00811 00812 httpServerResponse.Response = SL_NETAPP_RESPONSE_NONE; 00813 00814 00815 _SlDrvHandleHttpServerEvents (&httpServerEvent, &httpServerResponse); 00816 } 00817 break; 00818 #endif 00819 default: 00820 SL_ERROR_TRACE2(MSG_305, "ASSERT: _SlDrvNetAppEventHandler : invalid opcode = 0x%x = %i", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode); 00821 VERIFY_PROTOCOL(0); 00822 } 00823 } 00824 00825 /* 00826 * ASYNCHRONOUS EVENT HANDLERS -- Start 00827 */ 00828 00829 /*! 00830 \brief This function handles WLAN events 00831 00832 \param[in] pWlanEvent is the event passed to the handler 00833 00834 \return None 00835 00836 \note 00837 00838 \warning 00839 */ 00840 #if (defined(sl_WlanEvtHdlr)) 00841 void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) 00842 { 00843 unsigned char g_ucConnectionSSID[32+1]; //Connection SSID 00844 unsigned char g_ucConnectionBSSID[6]; //Connection BSSID 00845 00846 if(pWlanEvent == NULL) 00847 printf(" [WLAN EVENT] NULL Pointer Error \n\r"); 00848 00849 switch(pWlanEvent->Event) { 00850 case SL_WLAN_CONNECT_EVENT: { 00851 _cc3100_->SET_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); 00852 00853 // Copy new connection SSID and BSSID to global parameters 00854 memcpy(g_ucConnectionSSID,pWlanEvent->EventData. 00855 STAandP2PModeWlanConnected.ssid_name, 00856 pWlanEvent->EventData.STAandP2PModeWlanConnected.ssid_len); 00857 memcpy(g_ucConnectionBSSID, 00858 pWlanEvent->EventData.STAandP2PModeWlanConnected.bssid, 00859 SL_BSSID_LENGTH); 00860 00861 printf("[WLAN EVENT] STA Connected to the AP: %s ," 00862 "BSSID: %x:%x:%x:%x:%x:%x\n\r", 00863 g_ucConnectionSSID,g_ucConnectionBSSID[0], 00864 g_ucConnectionBSSID[1],g_ucConnectionBSSID[2], 00865 g_ucConnectionBSSID[3],g_ucConnectionBSSID[4], 00866 g_ucConnectionBSSID[5]); 00867 /* 00868 * Information about the connected AP (like name, MAC etc) will be 00869 * available in 'slWlanConnectAsyncResponse_t' - Applications 00870 * can use it if required 00871 * 00872 * slWlanConnectAsyncResponse_t *pEventData = NULL; 00873 * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected; 00874 * 00875 */ 00876 } 00877 break; 00878 00879 case SL_WLAN_DISCONNECT_EVENT: { 00880 slWlanConnectAsyncResponse_t* pEventData = NULL; 00881 00882 _cc3100_->CLR_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); 00883 _cc3100_->CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED); 00884 00885 pEventData = &pWlanEvent->EventData.STAandP2PModeDisconnected; 00886 00887 /* If the user has initiated 'Disconnect' request, 'reason_code' is SL_USER_INITIATED_DISCONNECTION */ 00888 if(SL_USER_INITIATED_DISCONNECTION == pEventData->reason_code) { 00889 printf("[WLAN EVENT]Device disconnected from the AP: %s," 00890 "BSSID: %x:%x:%x:%x:%x:%x on application's request \n\r", 00891 g_ucConnectionSSID,g_ucConnectionBSSID[0], 00892 g_ucConnectionBSSID[1],g_ucConnectionBSSID[2], 00893 g_ucConnectionBSSID[3],g_ucConnectionBSSID[4], 00894 g_ucConnectionBSSID[5]); 00895 } else { 00896 printf("[WLAN ERROR]Device disconnected from the AP AP: %s," 00897 "BSSID: %x:%x:%x:%x:%x:%x on an ERROR..!! \n\r", 00898 g_ucConnectionSSID,g_ucConnectionBSSID[0], 00899 g_ucConnectionBSSID[1],g_ucConnectionBSSID[2], 00900 g_ucConnectionBSSID[3],g_ucConnectionBSSID[4], 00901 g_ucConnectionBSSID[5]); 00902 } 00903 memset(g_ucConnectionSSID,0,sizeof(g_ucConnectionSSID)); 00904 memset(g_ucConnectionBSSID,0,sizeof(g_ucConnectionBSSID)); 00905 } 00906 break; 00907 00908 case SL_WLAN_STA_CONNECTED_EVENT: { 00909 _cc3100_->SET_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED); 00910 } 00911 break; 00912 00913 case SL_WLAN_STA_DISCONNECTED_EVENT: { 00914 _cc3100_->CLR_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED); 00915 _cc3100_->CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED); 00916 } 00917 break; 00918 00919 default: { 00920 printf("[WLAN EVENT] Unexpected event [0x%x]\n\r",pWlanEvent->Event); 00921 } 00922 break; 00923 } 00924 } 00925 #endif 00926 00927 /*! 00928 \brief This function handles events for IP address acquisition via DHCP 00929 indication 00930 00931 \param[in] pNetAppEvent is the event passed to the handler 00932 00933 \return None 00934 00935 \note 00936 00937 \warning 00938 */ 00939 #if (defined(sl_NetAppEvtHdlr)) 00940 void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) 00941 { 00942 00943 if(pNetAppEvent == NULL){ 00944 printf(" [NETAPP EVENT] NULL Pointer Error \n\r"); 00945 } 00946 00947 switch(pNetAppEvent->Event) { 00948 case SL_NETAPP_IPV4_IPACQUIRED_EVENT: { 00949 SlIpV4AcquiredAsync_t *pEventData = NULL; 00950 _cc3100_->SET_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED); 00951 pEventData = &pNetAppEvent->EventData.ipAcquiredV4; 00952 g_GatewayIP = pEventData->gateway; 00953 00954 printf("[NETAPP EVENT] IP Acquired: IP=%d.%d.%d.%d , ""Gateway=%d.%d.%d.%d\n\r", 00955 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,3), 00956 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,2), 00957 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,1), 00958 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,0), 00959 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,3), 00960 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,2), 00961 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,1), 00962 _cc3100_->_netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,0)); 00963 00964 } 00965 break; 00966 00967 case SL_NETAPP_IP_LEASED_EVENT: { 00968 g_StationIP = pNetAppEvent->EventData.ipLeased.ip_address; 00969 _cc3100_->SET_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED); 00970 00971 } 00972 break; 00973 00974 default: { 00975 printf("[NETAPP EVENT] Unexpected event [0x%x] \n\r",pNetAppEvent->Event); 00976 } 00977 break; 00978 } 00979 } 00980 #endif 00981 00982 /*! 00983 \brief This function handles socket events indication 00984 00985 \param[in] pSock is the event passed to the handler 00986 00987 \return None 00988 */ 00989 #if (defined(sl_SockEvtHdlr)) 00990 void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) 00991 { 00992 if(pSock == NULL) 00993 printf(" [SOCK EVENT] NULL Pointer Error \n\r"); 00994 00995 switch( pSock->Event ) 00996 { 00997 case SL_SOCKET_TX_FAILED_EVENT: 00998 /* 00999 * TX Failed 01000 * 01001 * Information about the socket descriptor and status will be 01002 * available in 'SlSockEventData_t' - Applications can use it if 01003 * required 01004 * 01005 * SlSockEventData_t *pEventData = NULL; 01006 * pEventData = & pSock->EventData; 01007 */ 01008 01009 switch( pSock->socketAsyncEvent.SockTxFailData.status ) 01010 { 01011 case SL_ECLOSE: 01012 printf(" [SOCK EVENT] Close socket operation, failed to transmit all queued packets\n\r"); 01013 break; 01014 default: 01015 printf("[SOCK ERROR] - TX FAILED : socket %d , reason""(%d) \n\n", pSock->socketAsyncEvent.SockTxFailData.sd, pSock->socketAsyncEvent.SockTxFailData.status); 01016 break; 01017 } 01018 break; 01019 01020 default: 01021 printf("[SOCK EVENT] - Unexpected Event [%x0x]\n\n",pSock->Event); 01022 break; 01023 } 01024 } 01025 #endif 01026 01027 /*! 01028 \brief This function handles callback for the HTTP server events 01029 01030 \param[in] pHttpEvent - Contains the relevant event information 01031 \param[in] pHttpResponse - Should be filled by the user with the 01032 relevant response information 01033 01034 \return None 01035 01036 \note 01037 01038 \warning 01039 */ 01040 #if (defined(sl_HttpServerCallback)) 01041 void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse) 01042 { 01043 /* 01044 * This application doesn't work with HTTP server - Hence these 01045 * events are not handled here 01046 */ 01047 printf(" [HTTP EVENT] Unexpected event \n\r"); 01048 } 01049 #endif 01050 /*! 01051 \brief This function handles general error events indication 01052 01053 \param[in] pDevEvent is the event passed to the handler 01054 01055 \return None 01056 */ 01057 #if (defined(sl_GeneralEvtHdlr)) 01058 void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) 01059 { 01060 /* 01061 * Most of the general errors are not FATAL are are to be handled 01062 * appropriately by the application 01063 */ 01064 printf("[GENERAL EVENT] - ID=[%d] Sender=[%d]\n\n", pDevEvent->EventData.deviceEvent.status, pDevEvent->EventData.deviceEvent.sender); 01065 } 01066 #endif 01067 01068 #ifdef __cplusplus 01069 } 01070 #endif /* __cplusplus */ 01071 01072 //}//namespace
Generated on Sun Jul 17 2022 07:25:50 by 1.7.2