TI's MQTT Demo with freertos CM4F

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_netapp.cpp Source File

cc3100_netapp.cpp

00001 /*
00002  * netapp.c - 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 
00038 
00039 /*****************************************************************************/
00040 /* Include files                                                             */
00041 /*****************************************************************************/
00042 #include "cc3100_simplelink.h"
00043 #include "cc3100_protocol.h"
00044 #include "cc3100_driver.h"
00045 
00046 #include "cc3100_netapp.h"
00047 #include "fPtr_func.h"
00048 
00049 namespace mbed_cc3100 {
00050 
00051 /*****************************************************************************/
00052 /* Macro declarations                                                        */
00053 /*****************************************************************************/
00054 const uint32_t NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT           =       ((uint32_t)0x1 << 31);
00055 
00056 #ifdef SL_TINY
00057 const uint8_t NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH   =      63;
00058 #else
00059 const uint8_t NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH   =      255;
00060 #endif
00061 
00062 #ifndef SL_PLATFORM_MULTI_THREADED  
00063 cc3100_netapp::cc3100_netapp(cc3100_driver &driver, cc3100_nonos &nonos)
00064     : _driver(driver), _nonos(nonos)
00065 {
00066 }
00067 #else
00068 cc3100_netapp::cc3100_netapp(cc3100_driver &driver)
00069     : _driver(driver)
00070 {
00071 }
00072 #endif
00073 cc3100_netapp::~cc3100_netapp()
00074 {
00075 
00076 }
00077 
00078 
00079 /*****************************************************************************/
00080 /* API functions                                                             */
00081 /*****************************************************************************/
00082 
00083 /*****************************************************************************
00084  sl_NetAppStart
00085 *****************************************************************************/
00086 typedef union {
00087     _NetAppStartStopCommand_t       Cmd;
00088     _NetAppStartStopResponse_t   Rsp;
00089 } _SlNetAppStartStopMsg_u;
00090 
00091 #if _SL_INCLUDE_FUNC(sl_NetAppStart)
00092 const _SlCmdCtrl_t _SlNetAppStartCtrl = {
00093     SL_OPCODE_NETAPP_START_COMMAND,
00094     sizeof(_NetAppStartStopCommand_t),
00095     sizeof(_NetAppStartStopResponse_t)
00096 };
00097 
00098 int16_t cc3100_netapp::sl_NetAppStart(const uint32_t AppBitMap)
00099 {
00100     _SlNetAppStartStopMsg_u Msg;
00101     Msg.Cmd.appId = AppBitMap;
00102     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppStartCtrl, &Msg, NULL));
00103 
00104     return Msg.Rsp.status;
00105 }
00106 #endif
00107 
00108 /*****************************************************************************
00109  sl_NetAppStop
00110 *****************************************************************************/
00111 #if _SL_INCLUDE_FUNC(sl_NetAppStop)
00112 const _SlCmdCtrl_t _SlNetAppStopCtrl =
00113 {
00114     SL_OPCODE_NETAPP_STOP_COMMAND,
00115     sizeof(_NetAppStartStopCommand_t),
00116     sizeof(_NetAppStartStopResponse_t)
00117 };
00118 int16_t cc3100_netapp::sl_NetAppStop(const uint32_t AppBitMap)
00119 {
00120     _SlNetAppStartStopMsg_u Msg;
00121     Msg.Cmd.appId = AppBitMap;
00122     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppStopCtrl, &Msg, NULL));
00123 
00124     return Msg.Rsp.status;
00125 }
00126 #endif
00127 
00128 
00129 /******************************************************************************/
00130 /* sl_NetAppGetServiceList */
00131 /******************************************************************************/
00132 typedef struct {
00133     uint8_t  IndexOffest;
00134     uint8_t  MaxServiceCount;
00135     uint8_t  Flags;
00136     int8_t  Padding;
00137 } NetappGetServiceListCMD_t;
00138 
00139 typedef union {
00140     NetappGetServiceListCMD_t      Cmd;
00141     _BasicResponse_t                Rsp;
00142 } _SlNetappGetServiceListMsg_u;
00143 
00144 #if _SL_INCLUDE_FUNC(sl_NetAppGetServiceList)
00145 const _SlCmdCtrl_t _SlGetServiceListeCtrl = {
00146     SL_OPCODE_NETAPP_NETAPP_MDNS_LOOKUP_SERVICE,
00147     sizeof(NetappGetServiceListCMD_t),
00148     sizeof(_BasicResponse_t)
00149 };
00150 
00151 int16_t cc3100_netapp::sl_NetAppGetServiceList(const uint8_t  IndexOffest,
00152         const uint8_t  MaxServiceCount,
00153         const uint8_t  Flags,
00154         int8_t  *pBuffer,
00155         const uint32_t  RxBufferLength
00156                                               )
00157 {
00158     int32_t                      retVal= 0;
00159     _SlNetappGetServiceListMsg_u Msg;
00160     _SlCmdExt_t                  CmdExt;
00161     uint16_t               ServiceSize = 0;
00162     uint16_t               BufferSize = 0;
00163 
00164     /*
00165     Calculate RX pBuffer size
00166     WARNING:
00167     if this size is BufferSize than 1480 error should be returned because there
00168     is no place in the RX packet.
00169     */
00170     switch(Flags) {
00171         case SL_NET_APP_FULL_SERVICE_WITH_TEXT_IPV4_TYPE:
00172             ServiceSize =  sizeof(SlNetAppGetFullServiceWithTextIpv4List_t);
00173             break;
00174 
00175         case SL_NET_APP_FULL_SERVICE_IPV4_TYPE:
00176             ServiceSize =  sizeof(SlNetAppGetFullServiceIpv4List_t);
00177             break;
00178 
00179         case SL_NET_APP_SHORT_SERVICE_IPV4_TYPE:
00180             ServiceSize =  sizeof(SlNetAppGetShortServiceIpv4List_t);
00181             break;
00182 
00183         default:
00184             ServiceSize =  sizeof(_BasicResponse_t);
00185             break;
00186     }
00187 
00188 
00189 
00190     BufferSize =  MaxServiceCount * ServiceSize;
00191 
00192     /*Check the size of the requested services is smaller than size of the user buffer.
00193       If not an error is returned in order to avoid overwriting memory. */
00194     if(RxBufferLength <= BufferSize) {
00195         return SL_ERROR_NETAPP_RX_BUFFER_LENGTH_ERROR;
00196     }
00197 
00198     _driver._SlDrvResetCmdExt(&CmdExt);
00199     CmdExt.RxPayloadLen = BufferSize;
00200 
00201     CmdExt.pRxPayload = (uint8_t *)pBuffer;
00202 
00203     Msg.Cmd.IndexOffest     = IndexOffest;
00204     Msg.Cmd.MaxServiceCount = MaxServiceCount;
00205     Msg.Cmd.Flags           = Flags;
00206     Msg.Cmd.Padding         = 0;
00207 
00208     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetServiceListeCtrl, &Msg, &CmdExt));
00209     retVal = Msg.Rsp.status;
00210 
00211     return (int16_t)retVal;
00212 }
00213 
00214 #endif
00215 
00216 /*****************************************************************************/
00217 /* sl_mDNSRegisterService */
00218 /*****************************************************************************/
00219 /*
00220  * The below struct depicts the constant parameters of the command/API RegisterService.
00221  *
00222    1. ServiceLen                      - The length of the service should be smaller than NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00223    2. TextLen                         - The length of the text should be smaller than NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00224    3. port                            - The port on this target host.
00225    4. TTL                             - The TTL of the service
00226    5. Options                         - bitwise parameters:
00227                                         bit 0  - is unique (means if the service needs to be unique)
00228                                         bit 31  - for internal use if the service should be added or deleted (set means ADD).
00229                                         bit 1-30 for future.
00230 
00231    NOTE:
00232 
00233    1. There are another variable parameter is this API which is the service name and the text.
00234    2. According to now there is no warning and Async event to user on if the service is a unique.
00235 *
00236  */
00237 
00238 typedef struct {
00239     uint8_t   ServiceNameLen;
00240     uint8_t   TextLen;
00241     uint16_t  Port;
00242     uint32_t   TTL;
00243     uint32_t   Options;
00244 } NetappMdnsSetService_t;
00245 
00246 typedef union {
00247     NetappMdnsSetService_t         Cmd;
00248     _BasicResponse_t                Rsp;
00249 } _SlNetappMdnsRegisterServiceMsg_u;
00250 
00251 #if _SL_INCLUDE_FUNC(sl_NetAppMDNSRegisterUnregisterService)
00252 const _SlCmdCtrl_t _SlRegisterServiceCtrl = {
00253     SL_OPCODE_NETAPP_MDNSREGISTERSERVICE,
00254     sizeof(NetappMdnsSetService_t),
00255     sizeof(_BasicResponse_t)
00256 };
00257 
00258 /******************************************************************************
00259 
00260     sl_NetAppMDNSRegisterService
00261 
00262     CALLER          user from its host
00263 
00264 
00265     DESCRIPTION:
00266                     Add/delete  service
00267                     The function manipulates the command that register the service and call
00268                     to the NWP in order to add/delete the service to/from the mDNS package and to/from the DB.
00269 
00270                     This register service is a service offered by the application.
00271                     This unregister service is a service offered by the application before.
00272 
00273                     The service name should be full service name according to RFC
00274                     of the DNS-SD - means the value in name field in SRV answer.
00275 
00276                     Example for service name:
00277                     1. PC1._ipp._tcp.local
00278                     2. PC2_server._ftp._tcp.local
00279 
00280                     If the option is_unique is set, mDNS probes the service name to make sure
00281                     it is unique before starting to announce the service on the network.
00282                     Instance is the instance portion of the service name.
00283 
00284 
00285 
00286 
00287     PARAMETERS:
00288 
00289                     The command is from constant parameters and variables parameters.
00290 
00291                     Constant parameters are:
00292 
00293                     ServiceLen                          - The length of the service.
00294                     TextLen                             - The length of the service should be smaller than 64.
00295                     port                                - The port on this target host.
00296                     TTL                                 - The TTL of the service
00297                     Options                             - bitwise parameters:
00298                                                             bit 0  - is unique (means if the service needs to be unique)
00299                                                             bit 31  - for internal use if the service should be added or deleted (set means ADD).
00300                                                             bit 1-30 for future.
00301 
00302                    The variables parameters are:
00303 
00304                     Service name(full service name)     - The service name.
00305                                                           Example for service name:
00306                                                           1. PC1._ipp._tcp.local
00307                                                           2. PC2_server._ftp._tcp.local
00308 
00309                     Text                                - The description of the service.
00310                                                           should be as mentioned in the RFC
00311                                                           (according to type of the service IPP,FTP...)
00312 
00313                     NOTE - pay attention
00314 
00315                         1. Temporary -  there is an allocation on stack of internal buffer.
00316                         Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00317                         It means that the sum of the text length and service name length cannot be bigger than
00318                         NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00319                         If it is - An error is returned.
00320 
00321                         2. According to now from certain constraints the variables parameters are set in the
00322                         attribute part (contain constant parameters)
00323 
00324 
00325 
00326       RETURNS:        Status - the immediate response of the command status.
00327                                0 means success.
00328 
00329 
00330 
00331 ******************************************************************************/
00332 int16_t cc3100_netapp::sl_NetAppMDNSRegisterUnregisterService(const char* pServiceName, 
00333                                                               const uint8_t ServiceNameLen, 
00334                                                               const char* pText, 
00335                                                               const uint8_t TextLen, 
00336                                                               const uint16_t Port, 
00337                                                               const uint32_t TTL, 
00338                                                               const uint32_t Options)
00339 {
00340 
00341     _SlNetappMdnsRegisterServiceMsg_u Msg;
00342     _SlCmdExt_t CmdExt ;
00343     unsigned char ServiceNameAndTextBuffer[NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH];
00344     unsigned char *TextPtr;
00345 
00346     /*
00347 
00348     NOTE - pay attention
00349 
00350         1. Temporary -  there is an allocation on stack of internal buffer.
00351         Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00352         It means that the sum of the text length and service name length cannot be bigger than
00353         NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00354         If it is - An error is returned.
00355 
00356         2. According to now from certain constraints the variables parameters are set in the
00357         attribute part (contain constant parameters)
00358 
00359 
00360     */
00361 
00362     /*build the attribute part of the command.
00363       It contains the constant parameters of the command*/
00364 
00365     Msg.Cmd.ServiceNameLen  = ServiceNameLen;
00366     Msg.Cmd.Options         = Options;
00367     Msg.Cmd.Port            = Port;
00368     Msg.Cmd.TextLen         = TextLen;
00369     Msg.Cmd.TTL             = TTL;
00370 
00371     /*Build the payload part of the command
00372      Copy the service name and text to one buffer.
00373      NOTE - pay attention
00374                 The size of the service length + the text length should be smaller than 255,
00375                 Until the simplelink drive supports to variable length through SPI command. */
00376     if(TextLen + ServiceNameLen > (NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH - 1 )) { /*-1 is for giving a place to set null termination at the end of the text*/
00377         return -1;
00378     }
00379 
00380     _driver._SlDrvMemZero(ServiceNameAndTextBuffer, NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH);
00381 
00382 
00383     /*Copy the service name*/
00384     memcpy(ServiceNameAndTextBuffer,
00385               pServiceName,
00386               ServiceNameLen);
00387 
00388     if(TextLen > 0 ) {
00389 
00390         TextPtr = &ServiceNameAndTextBuffer[ServiceNameLen];
00391         /*Copy the text just after the service name*/
00392         memcpy(TextPtr, pText, TextLen);
00393     }
00394 
00395     _driver._SlDrvResetCmdExt(&CmdExt);
00396     CmdExt.TxPayloadLen = (TextLen + ServiceNameLen);
00397     CmdExt.pTxPayload   = (uint8_t *)ServiceNameAndTextBuffer;
00398 
00399 
00400     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlRegisterServiceCtrl, &Msg, &CmdExt));
00401 
00402     return (int16_t)Msg.Rsp.status;
00403 
00404 
00405 }
00406 #endif
00407 
00408 /**********************************************************************************************/
00409 #if _SL_INCLUDE_FUNC(sl_NetAppMDNSRegisterService)
00410 int16_t cc3100_netapp::sl_NetAppMDNSRegisterService(const char* pServiceName, 
00411                                                     const uint8_t ServiceNameLen, 
00412                                                     const char* pText, 
00413                                                     const uint8_t TextLen, 
00414                                                     const uint16_t Port, 
00415                                                     const uint32_t TTL, 
00416                                                     uint32_t Options)
00417 {
00418 
00419     /*
00420 
00421     NOTE - pay attention
00422 
00423     1. Temporary -  there is an allocation on stack of internal buffer.
00424     Its size is NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00425     It means that the sum of the text length and service name length cannot be bigger than
00426     NETAPP_MDNS_MAX_SERVICE_NAME_AND_TEXT_LENGTH.
00427     If it is - An error is returned.
00428 
00429     2. According to now from certain constraints the variables parameters are set in the
00430     attribute part (contain constant parameters)
00431 
00432     */
00433 
00434     /*Set the add service bit in the options parameter.
00435       In order not use different opcodes for the register service and unregister service
00436       bit 31 in option is taken for this purpose. if it is set it means in NWP that the service should be added
00437       if it is cleared it means that the service should be deleted and there is only meaning to pServiceName
00438       and ServiceNameLen values. */
00439     Options |=  NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT;
00440 
00441     return  (sl_NetAppMDNSRegisterUnregisterService(    pServiceName, ServiceNameLen, pText, TextLen, Port, TTL, Options));
00442 
00443 
00444 }
00445 #endif
00446 /**********************************************************************************************/
00447 
00448 
00449 
00450 /**********************************************************************************************/
00451 #if _SL_INCLUDE_FUNC(sl_NetAppMDNSUnRegisterService)
00452 int16_t cc3100_netapp::sl_NetAppMDNSUnRegisterService(const char* pServiceName, const uint8_t ServiceNameLen)
00453 {
00454     uint32_t    Options = 0;
00455 
00456     /*
00457 
00458     NOTE - pay attention
00459 
00460             The size of the service length  should be smaller than 255,
00461             Until the simplelink drive supports to variable length through SPI command.
00462 
00463 
00464     */
00465 
00466     /*Clear the add service bit in the options parameter.
00467       In order not use different opcodes for the register service and unregister service
00468       bit 31 in option is taken for this purpose. if it is set it means in NWP that the service should be added
00469       if it is cleared it means that the service should be deleted and there is only meaning to pServiceName
00470       and ServiceNameLen values.*/
00471 
00472     Options &=  (~NETAPP_MDNS_OPTIONS_ADD_SERVICE_BIT);
00473 
00474     return  (sl_NetAppMDNSRegisterUnregisterService(pServiceName, ServiceNameLen, NULL, 0, 0, 0, Options));
00475 
00476 
00477 }
00478 #endif
00479 /**********************************************************************************************/
00480 
00481 
00482 
00483 /*****************************************************************************/
00484 /* sl_DnsGetHostByService */
00485 /*****************************************************************************/
00486 /*
00487  * The below struct depicts the constant parameters of the command/API sl_DnsGetHostByService.
00488  *
00489    1. ServiceLen                      - The length of the service should be smaller than 255.
00490    2. AddrLen                         - TIPv4 or IPv6 (SL_AF_INET , SL_AF_INET6).
00491 *
00492  */
00493 
00494 typedef struct {
00495     uint8_t   ServiceLen;
00496     uint8_t   AddrLen;
00497     uint16_t  Padding;
00498 } _GetHostByServiceCommand_t;
00499 
00500 
00501 
00502 /*
00503  * The below structure depict the constant parameters that are returned in the Async event answer
00504  * according to command/API sl_DnsGetHostByService for IPv4 and IPv6.
00505  *
00506     1Status                     - The status of the response.
00507     2.Address                       - Contains the IP address of the service.
00508     3.Port                          - Contains the port of the service.
00509     4.TextLen                       - Contains the max length of the text that the user wants to get.
00510                                                 it means that if the test of service is bigger that its value than
00511                                                 the text is cut to inout_TextLen value.
00512                                         Output: Contain the length of the text that is returned. Can be full text or part
00513                                                 of the text (see above).
00514 
00515 *
00516  
00517 typedef struct {
00518     uint16_t   Status;
00519     uint16_t   TextLen;
00520     uint32_t    Port;
00521     uint32_t    Address;
00522 } _GetHostByServiceIPv4AsyncResponse_t;
00523 */
00524 
00525 typedef struct {
00526     uint16_t   Status;
00527     uint16_t   TextLen;
00528     uint32_t    Port;
00529     uint32_t    Address[4];
00530 } _GetHostByServiceIPv6AsyncResponse_t;
00531 
00532 
00533 typedef union {
00534     _GetHostByServiceIPv4AsyncResponse_t IpV4;
00535     _GetHostByServiceIPv6AsyncResponse_t IpV6;
00536 } _GetHostByServiceAsyncResponseAttribute_u;
00537 
00538 typedef union {
00539     _GetHostByServiceCommand_t      Cmd;
00540     _BasicResponse_t                Rsp;
00541 } _SlGetHostByServiceMsg_u;
00542 
00543 #if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByService)
00544 const _SlCmdCtrl_t _SlGetHostByServiceCtrl = {
00545     SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICE,
00546     sizeof(_GetHostByServiceCommand_t),
00547     sizeof(_BasicResponse_t)
00548 };
00549 
00550 int32_t cc3100_netapp::sl_NetAppDnsGetHostByService(unsigned char *pServiceName,    /* string containing all (or only part): name + subtype + service */
00551         const uint8_t ServiceLen,
00552         const uint8_t Family,           /* 4-IPv4 , 16-IPv6 */
00553         uint32_t pAddr[],
00554         uint32_t *pPort,
00555         uint16_t *pTextLen, /* in: max len , out: actual len */
00556         unsigned char *pText)
00557 {
00558 
00559     _SlGetHostByServiceMsg_u         Msg;
00560     _SlCmdExt_t                      CmdExt ;
00561     _GetHostByServiceAsyncResponse_t AsyncRsp;
00562     uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
00563 
00564     /*
00565         Note:
00566         1. The return's attributes are belonged to first service that is found.
00567         It can be other services with the same service name will response to
00568         the query. The results of these responses are saved in the peer cache of the NWP, and
00569         should be read by another API.
00570 
00571         2. Text length can be 120 bytes only - not more
00572         It is because of constraints in the NWP on the buffer that is allocated for the Async event.
00573 
00574         3.The API waits to Async event by blocking. It means that the API is finished only after an Async event
00575         is sent by the NWP.
00576 
00577         4.No rolling option!!! - only PTR type is sent.
00578 
00579 
00580     */
00581     /*build the attribute part of the command.
00582       It contains the constant parameters of the command */
00583 
00584     Msg.Cmd.ServiceLen = ServiceLen;
00585     Msg.Cmd.AddrLen    = Family;
00586 
00587     /*Build the payload part of the command
00588       Copy the service name and text to one buffer.*/
00589     _driver._SlDrvResetCmdExt(&CmdExt);  
00590     CmdExt.TxPayloadLen = ServiceLen;
00591     
00592     CmdExt.pTxPayload   = (uint8_t *)pServiceName;
00593     
00594 
00595     /*set pointers to the output parameters (the returned parameters).
00596       This pointers are belonged to local struct that is set to global Async response parameter.
00597       It is done in order not to run more than one sl_DnsGetHostByService at the same time.
00598       The API should be run only if global parameter is pointed to NULL. */
00599     AsyncRsp.out_pText     = pText;
00600     AsyncRsp.inout_TextLen = (uint16_t* )pTextLen;
00601     AsyncRsp.out_pPort     = pPort;
00602     AsyncRsp.out_pAddr     = (uint32_t *)pAddr;
00603 
00604 
00605     ObjIdx = _driver._SlDrvProtectAsyncRespSetting((uint8_t*)&AsyncRsp, GETHOSYBYSERVICE_ID, SL_MAX_SOCKETS);
00606 
00607     if (MAX_CONCURRENT_ACTIONS == ObjIdx)
00608     {
00609         return SL_POOL_IS_EMPTY;
00610     }
00611 
00612     if (SL_AF_INET6 == Family) {
00613         g_pCB->ObjPool[ObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK;
00614     }
00615     /* Send the command */
00616     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByServiceCtrl, &Msg, &CmdExt));
00617 
00618 
00619 
00620     /* If the immediate reponse is O.K. than  wait for aSYNC event response. */
00621     if(SL_RET_CODE_OK == Msg.Rsp.status) {
00622         _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
00623 
00624         /* If we are - it means that Async event was sent.
00625            The results are copied in the Async handle return functions */
00626 
00627         Msg.Rsp.status = AsyncRsp.Status;
00628     }
00629 
00630     _driver._SlDrvReleasePoolObj(ObjIdx);
00631     return Msg.Rsp.status;
00632 }
00633 #endif
00634 
00635 /*****************************************************************************/
00636 /*  _sl_HandleAsync_DnsGetHostByAddr */
00637 /*****************************************************************************/
00638 #ifndef SL_TINY_EXT
00639 void cc3100_netapp::_sl_HandleAsync_DnsGetHostByAddr(void *pVoidBuf)
00640 {
00641     SL_TRACE0(DBG_MSG, MSG_303, "STUB: _sl_HandleAsync_DnsGetHostByAddr not implemented yet!");
00642     return;
00643 }
00644 #endif
00645 /*****************************************************************************/
00646 /* sl_DnsGetHostByName */
00647 /*****************************************************************************/
00648 typedef union {
00649     _GetHostByNameIPv4AsyncResponse_t IpV4;
00650     _GetHostByNameIPv6AsyncResponse_t IpV6;
00651 } _GetHostByNameAsyncResponse_u;
00652 
00653 typedef union {
00654     _GetHostByNameCommand_t         Cmd;
00655     _BasicResponse_t                Rsp;
00656 } _SlGetHostByNameMsg_u;
00657 
00658 #if _SL_INCLUDE_FUNC(sl_NetAppDnsGetHostByName)
00659 const _SlCmdCtrl_t _SlGetHostByNameCtrl = {
00660     SL_OPCODE_NETAPP_DNSGETHOSTBYNAME,
00661     sizeof(_GetHostByNameCommand_t),
00662     sizeof(_BasicResponse_t)
00663 };
00664 
00665 int16_t cc3100_netapp::sl_NetAppDnsGetHostByName(unsigned char * hostname, const uint16_t usNameLen, uint32_t*  out_ip_addr, const uint8_t family)
00666 {
00667     _SlGetHostByNameMsg_u           Msg;
00668     _SlCmdExt_t                     ExtCtrl;
00669     _GetHostByNameAsyncResponse_u   AsyncRsp;
00670     uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
00671     
00672     _driver._SlDrvResetCmdExt(&ExtCtrl);
00673     ExtCtrl.TxPayloadLen = usNameLen;
00674     
00675     ExtCtrl.pTxPayload = (unsigned char *)hostname;
00676     
00677 
00678     Msg.Cmd.Len = usNameLen;
00679     Msg.Cmd.family = family;
00680 
00681     /*Use Obj to issue the command, if not available try later */
00682     ObjIdx = (uint8_t)_driver._SlDrvWaitForPoolObj(GETHOSYBYNAME_ID,SL_MAX_SOCKETS);
00683     if (MAX_CONCURRENT_ACTIONS == ObjIdx) {
00684         printf("SL_POOL_IS_EMPTY \r\n");
00685         return SL_POOL_IS_EMPTY;
00686     }
00687     
00688     _driver._SlDrvProtectionObjLockWaitForever();
00689     
00690     g_pCB->ObjPool[ObjIdx].pRespArgs =  (uint8_t *)&AsyncRsp;
00691     /*set bit to indicate IPv6 address is expected */
00692     if (SL_AF_INET6 == family) {
00693         g_pCB->ObjPool[ObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK;
00694     }
00695 
00696      _driver._SlDrvProtectionObjUnLock();
00697     
00698     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByNameCtrl, &Msg, &ExtCtrl));
00699 
00700     if(SL_RET_CODE_OK == Msg.Rsp.status) {
00701         _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
00702         Msg.Rsp.status = AsyncRsp.IpV4.status;
00703 
00704         if(SL_OS_RET_CODE_OK == (int16_t)Msg.Rsp.status) {
00705             memcpy((int8_t *)out_ip_addr, (signed char *)&AsyncRsp.IpV4.ip0, (SL_AF_INET == family) ? SL_IPV4_ADDRESS_SIZE : SL_IPV6_ADDRESS_SIZE);
00706         }
00707     }
00708     _driver._SlDrvReleasePoolObj(ObjIdx);
00709     return Msg.Rsp.status;
00710 }
00711 #endif
00712 
00713 #ifndef SL_TINY_EXT
00714 void cc3100_netapp::CopyPingResultsToReport(_PingReportResponse_t *pResults,SlPingReport_t *pReport)
00715 {
00716     pReport->PacketsSent     = pResults->numSendsPings;
00717     pReport->PacketsReceived = pResults->numSuccsessPings;
00718     pReport->MinRoundTime    = pResults->rttMin;
00719     pReport->MaxRoundTime    = pResults->rttMax;
00720     pReport->AvgRoundTime    = pResults->rttAvg;
00721     pReport->TestTime        = pResults->testTime;
00722 }
00723 #endif
00724 /*****************************************************************************/
00725 /* sl_PingStart */
00726 /*****************************************************************************/
00727 typedef union {
00728     _PingStartCommand_t   Cmd;
00729     _PingReportResponse_t  Rsp;
00730 } _SlPingStartMsg_u;
00731 
00732 
00733 typedef enum {
00734     CMD_PING_TEST_RUNNING = 0,
00735     CMD_PING_TEST_STOPPED
00736 } _SlPingStatus_e;
00737 
00738 P_SL_DEV_PING_CALLBACK  pPingCallBackFunc;
00739 
00740 #if _SL_INCLUDE_FUNC(sl_NetAppPingStart)
00741 int16_t cc3100_netapp::sl_NetAppPingStart(const SlPingStartCommand_t* pPingParams, const uint8_t family, SlPingReport_t *pReport, const P_SL_DEV_PING_CALLBACK pPingCallback)
00742 {
00743 
00744     _SlCmdCtrl_t                CmdCtrl = {0, sizeof(_PingStartCommand_t), sizeof(_BasicResponse_t)};
00745     _SlPingStartMsg_u           Msg;
00746     _PingReportResponse_t       PingRsp;
00747     uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
00748 
00749     if( 0 == pPingParams->Ip ) 
00750     { /* stop any ongoing ping */
00751         return _driver._SlDrvBasicCmd(SL_OPCODE_NETAPP_PINGSTOP);
00752     }
00753 
00754     if(SL_AF_INET == family) {
00755         CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART;
00756         memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV4_ADDRESS_SIZE);
00757     } else {
00758         CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART_V6;
00759         memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV6_ADDRESS_SIZE);
00760     }
00761 
00762     Msg.Cmd.pingIntervalTime        = pPingParams->PingIntervalTime;
00763     Msg.Cmd.PingSize                = pPingParams->PingSize;
00764     Msg.Cmd.pingRequestTimeout      = pPingParams->PingRequestTimeout;
00765     Msg.Cmd.totalNumberOfAttempts   = pPingParams->TotalNumberOfAttempts;
00766     Msg.Cmd.flags                   = pPingParams->Flags;
00767 
00768     if( pPingCallback ) {
00769         pPingCallBackFunc = pPingCallback;
00770     } else {
00771         /*Use Obj to issue the command, if not available try later */
00772         ObjIdx = (uint8_t)_driver._SlDrvWaitForPoolObj(PING_ID,SL_MAX_SOCKETS);
00773         if (MAX_CONCURRENT_ACTIONS == ObjIdx) {
00774             return SL_POOL_IS_EMPTY;
00775         }
00776 #ifndef SL_PLATFORM_MULTI_THREADED               
00777         OSI_RET_OK_CHECK(_nonos.sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
00778 #else        
00779         OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
00780 #endif        
00781         /* async response handler for non callback mode */
00782         g_pCB->ObjPool[ObjIdx].pRespArgs = (uint8_t *)&PingRsp;
00783         pPingCallBackFunc = NULL;
00784 #ifndef SL_PLATFORM_MULTI_THREADED
00785         OSI_RET_OK_CHECK(_nonos.sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
00786 #else        
00787         OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
00788 #endif        
00789     }
00790 
00791 
00792     VERIFY_RET_OK(_driver._SlDrvCmdOp(&CmdCtrl, &Msg, NULL));
00793     /*send the command*/
00794     if(CMD_PING_TEST_RUNNING == (int16_t)Msg.Rsp.status || CMD_PING_TEST_STOPPED == (int16_t)Msg.Rsp.status ) {
00795         /* block waiting for results if no callback function is used */
00796         if( NULL == pPingCallback ) {
00797             _driver._SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
00798             if( SL_OS_RET_CODE_OK == (int16_t)PingRsp.status ) {
00799                 CopyPingResultsToReport(&PingRsp,pReport);
00800             }
00801             _driver._SlDrvReleasePoolObj(ObjIdx);
00802         }
00803     } else {
00804         /* ping failure, no async response */
00805         if( NULL == pPingCallback ) {
00806             _driver._SlDrvReleasePoolObj(ObjIdx);
00807         }
00808     }
00809 
00810     return Msg.Rsp.status;
00811 }
00812 #endif
00813 
00814 /*****************************************************************************/
00815 /* sl_NetAppSet */
00816 /*****************************************************************************/
00817 typedef union {
00818     _NetAppSetGet_t    Cmd;
00819     _BasicResponse_t   Rsp;
00820 } _SlNetAppMsgSet_u;
00821 
00822 #if _SL_INCLUDE_FUNC(sl_NetAppSet)
00823 const _SlCmdCtrl_t _SlNetAppSetCmdCtrl = {
00824     SL_OPCODE_NETAPP_NETAPPSET,
00825     sizeof(_NetAppSetGet_t),
00826     sizeof(_BasicResponse_t)
00827 };
00828 
00829 int32_t cc3100_netapp::sl_NetAppSet(const uint8_t AppId ,const uint8_t Option, const uint8_t OptionLen, const uint8_t *pOptionValue)
00830 {
00831 
00832     _SlNetAppMsgSet_u         Msg;
00833     _SlCmdExt_t               CmdExt;
00834     
00835     _driver._SlDrvResetCmdExt(&CmdExt);
00836     CmdExt.TxPayloadLen = (OptionLen+3) & (~3);
00837     
00838     CmdExt.pTxPayload = (uint8_t *)pOptionValue;
00839     
00840     Msg.Cmd.AppId    = AppId;
00841     Msg.Cmd.ConfigLen   = OptionLen;
00842     Msg.Cmd.ConfigOpt   = Option;
00843 
00844     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppSetCmdCtrl, &Msg, &CmdExt));
00845 
00846     return (int16_t)Msg.Rsp.status;
00847 }
00848 #endif
00849 
00850 /*****************************************************************************/
00851 /* sl_NetAppSendTokenValue */
00852 /*****************************************************************************/
00853 typedef union {
00854     sl_NetAppHttpServerSendToken_t    Cmd;
00855     _BasicResponse_t   Rsp;
00856 } _SlNetAppMsgSendTokenValue_u;
00857 
00858 #if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS)
00859 const _SlCmdCtrl_t _SlNetAppSendTokenValueCmdCtrl = {
00860     SL_OPCODE_NETAPP_HTTPSENDTOKENVALUE,
00861     sizeof(sl_NetAppHttpServerSendToken_t),
00862     sizeof(_BasicResponse_t)
00863 };
00864 
00865 uint16_t cc3100_netapp::sl_NetAppSendTokenValue(slHttpServerData_t * Token_value)
00866 {
00867 
00868     _SlNetAppMsgSendTokenValue_u    Msg;
00869     _SlCmdExt_t                     CmdExt;
00870 
00871     CmdExt.TxPayloadLen = (Token_value->value_len+3) & (~3);
00872     CmdExt.RxPayloadLen = 0;
00873     CmdExt.pTxPayload = (uint8_t *) Token_value->token_value;
00874     CmdExt.pRxPayload = NULL;
00875 
00876     Msg.Cmd.token_value_len = Token_value->value_len;
00877     Msg.Cmd.token_name_len = Token_value->name_len;
00878     memcpy(&Msg.Cmd.token_name[0], Token_value->token_name, Token_value->name_len);
00879 
00880 
00881     VERIFY_RET_OK(_driver._SlDrvCmdSend((_SlCmdCtrl_t *)&_SlNetAppSendTokenValueCmdCtrl, &Msg, &CmdExt));
00882 
00883     return Msg.Rsp.status;
00884 }
00885 #endif
00886 
00887 /*****************************************************************************/
00888 /* sl_NetAppGet */
00889 /*****************************************************************************/
00890 typedef union {
00891     _NetAppSetGet_t     Cmd;
00892     _NetAppSetGet_t     Rsp;
00893 } _SlNetAppMsgGet_u;
00894 
00895 #if _SL_INCLUDE_FUNC(sl_NetAppGet)
00896 const _SlCmdCtrl_t _SlNetAppGetCmdCtrl = {
00897     SL_OPCODE_NETAPP_NETAPPGET,
00898     sizeof(_NetAppSetGet_t),
00899     sizeof(_NetAppSetGet_t)
00900 };
00901 
00902 int32_t cc3100_netapp::sl_NetAppGet(const uint8_t AppId, const uint8_t Option, uint8_t *pOptionLen, uint8_t *pOptionValue)
00903 {
00904     _SlNetAppMsgGet_u         Msg;
00905     _SlCmdExt_t               CmdExt;
00906 
00907     if (*pOptionLen == 0) {
00908         return SL_EZEROLEN;
00909     }
00910     
00911     _driver._SlDrvResetCmdExt(&CmdExt);
00912     CmdExt.RxPayloadLen = *pOptionLen;
00913     
00914     CmdExt.pRxPayload = (uint8_t *)pOptionValue;
00915 
00916     Msg.Cmd.AppId    = AppId;
00917     Msg.Cmd.ConfigOpt   = Option;
00918     VERIFY_RET_OK(_driver._SlDrvCmdOp((_SlCmdCtrl_t *)&_SlNetAppGetCmdCtrl, &Msg, &CmdExt));
00919 
00920 
00921     if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) {
00922         *pOptionLen = (uint8_t)CmdExt.RxPayloadLen;
00923         return SL_ESMALLBUF;
00924     } else {
00925         *pOptionLen = (uint8_t)CmdExt.ActualRxPayloadLen;
00926     }
00927 
00928     return (int16_t)Msg.Rsp.Status;
00929 }
00930 #endif
00931 
00932 #ifndef SL_PLATFORM_MULTI_THREADED
00933 cc3100_flowcont::cc3100_flowcont(cc3100_driver &driver, cc3100_nonos &nonos)
00934     : _driver(driver), _nonos(nonos)
00935 {
00936 }
00937 #else
00938 cc3100_flowcont::cc3100_flowcont(cc3100_driver &driver)
00939     : _driver(driver)
00940 {
00941 }
00942 #endif
00943 cc3100_flowcont::~cc3100_flowcont()
00944 {
00945 
00946 }
00947 #if 0
00948 /*****************************************************************************/
00949 /* _SlDrvFlowContInit */
00950 /*****************************************************************************/
00951 void cc3100_flowcont::_SlDrvFlowContInit(void)
00952 {
00953     g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN;
00954 
00955     OSI_RET_OK_CHECK(_nonos.sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj"));
00956 
00957     OSI_RET_OK_CHECK(_nonos.sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj"));
00958 }
00959 
00960 /*****************************************************************************/
00961 /* _SlDrvFlowContDeinit */
00962 /*****************************************************************************/
00963 void cc3100_flowcont::_SlDrvFlowContDeinit(void)
00964 {
00965     g_pCB->FlowContCB.TxPoolCnt = 0;
00966 
00967     OSI_RET_OK_CHECK(_nonos.sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj, 0));
00968 
00969     OSI_RET_OK_CHECK(_nonos.sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj, 0));
00970 }
00971 #endif
00972 }//namespace mbed_cc3100
00973 
00974