Home | History | Annotate | Download | only in snep
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This is the generic SNEP implementation file for the NFA SNEP.
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "nfa_api.h"
     26 #include "nfa_sys.h"
     27 #include "nfa_sys_int.h"
     28 #include "llcp_defs.h"
     29 #include "nfa_p2p_int.h"
     30 #include "nfa_snep_int.h"
     31 #include "nfa_mem_co.h"
     32 #include "trace_api.h"
     33 
     34 /*****************************************************************************
     35 **  Global Variables
     36 *****************************************************************************/
     37 
     38 /*****************************************************************************
     39 **  Static Functions
     40 *****************************************************************************/
     41 
     42 /* debug functions type */
     43 #if (BT_TRACE_VERBOSE == TRUE)
     44 static char *nfa_snep_opcode (UINT8 opcode);
     45 #endif
     46 
     47 /*****************************************************************************
     48 **  Constants
     49 *****************************************************************************/
     50 
     51 /*******************************************************************************
     52 **
     53 ** Function         nfa_snep_sap_to_index
     54 **
     55 ** Description      find a connection control block with SAP
     56 **
     57 **
     58 ** Returns          index of connection control block if success
     59 **                  NFA_SNEP_MAX_CONN, otherwise
     60 **
     61 *******************************************************************************/
     62 UINT8 nfa_snep_sap_to_index (UINT8 local_sap, UINT8 remote_sap, UINT8 flags)
     63 {
     64     UINT8 xx;
     65 
     66     for (xx = 0; xx < NFA_SNEP_MAX_CONN; xx++)
     67     {
     68         if (  (nfa_snep_cb.conn[xx].p_cback)
     69             &&(nfa_snep_cb.conn[xx].local_sap == local_sap)
     70             &&((remote_sap == NFA_SNEP_ANY_SAP) || (nfa_snep_cb.conn[xx].remote_sap == remote_sap))
     71             &&((nfa_snep_cb.conn[xx].flags & flags) == flags)  )
     72         {
     73             return xx;
     74         }
     75     }
     76     return NFA_SNEP_MAX_CONN;
     77 }
     78 
     79 /*******************************************************************************
     80 **
     81 ** Function         nfa_snep_allocate_cb
     82 **
     83 ** Description      Allocate a connection control block
     84 **
     85 **
     86 ** Returns          index of connection control block if success
     87 **                  NFA_SNEP_MAX_CONN, otherwise
     88 **
     89 *******************************************************************************/
     90 UINT8 nfa_snep_allocate_cb (void)
     91 {
     92     UINT8 xx;
     93 
     94     for (xx = 0; xx < NFA_SNEP_MAX_CONN; xx++)
     95     {
     96         if (nfa_snep_cb.conn[xx].p_cback == NULL)
     97         {
     98             memset (&nfa_snep_cb.conn[xx], 0x00, sizeof (tNFA_SNEP_CONN));
     99             return xx;
    100         }
    101     }
    102     return NFA_SNEP_MAX_CONN;
    103 }
    104 
    105 /*******************************************************************************
    106 **
    107 ** Function         nfa_snep_deallocate_cb
    108 **
    109 ** Description      Deallocate a connection control block
    110 **
    111 **
    112 ** Returns          void
    113 **
    114 *******************************************************************************/
    115 void nfa_snep_deallocate_cb (UINT8 xx)
    116 {
    117     nfa_snep_cb.conn[xx].p_cback = NULL;
    118 }
    119 
    120 /*******************************************************************************
    121 **
    122 ** Function         nfa_snep_timer_cback
    123 **
    124 ** Description      Process timeout event when timer expires
    125 **
    126 **
    127 ** Returns          None
    128 **
    129 *******************************************************************************/
    130 static void nfa_snep_timer_cback (void *p_tle)
    131 {
    132     UINT8 dlink = (UINT8) ((TIMER_LIST_ENT*)p_tle)->event;
    133 
    134     SNEP_TRACE_DEBUG1 ("nfa_snep_timer_cback () dlink = %d", dlink);
    135 
    136     /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
    137     nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
    138 
    139     LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    140                         nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    141 }
    142 
    143 /*******************************************************************************
    144 **
    145 ** Function         nfa_snep_get_efficent_miu
    146 **
    147 ** Description      Calculate best MIU to send data for throughput
    148 **
    149 **
    150 ** Returns          most efficent MIU for throughput
    151 **
    152 *******************************************************************************/
    153 static UINT16 nfa_snep_get_efficent_miu (UINT16 remote_miu, UINT8 remote_rw)
    154 {
    155     UINT16 local_link_miu, remote_link_miu;
    156     UINT16 max_num_pdu_in_agf;
    157     UINT16 efficent_miu;
    158 
    159     SNEP_TRACE_DEBUG2 ("nfa_snep_get_efficent_miu () remote_miu = %d, remote_rw = %d",
    160                         remote_miu, remote_rw);
    161 
    162     LLCP_GetLinkMIU (&local_link_miu, &remote_link_miu);
    163 
    164     /* local buffer size is small than max receiving size of peer */
    165     if (local_link_miu < remote_link_miu)
    166     {
    167         remote_link_miu = local_link_miu;
    168     }
    169 
    170     /*
    171     ** 9 bytes overhead if AGF is used
    172     **  - 2 byts AGF header
    173     **  - at least two of 2 bytes length field for I-PDU
    174     **  - 3 bytes header for I-PDU
    175     */
    176     if (remote_link_miu - remote_miu > 9)
    177     {
    178         /*
    179         ** 5 bytes overhead for each I-PDU in AGF
    180         **  - 2 bytes length field
    181         **  - 3 bytes header for I-PDU
    182         */
    183         max_num_pdu_in_agf = remote_link_miu / (remote_miu + 5);
    184 
    185         if (remote_link_miu % (remote_miu + 5))
    186         {
    187             max_num_pdu_in_agf += 1;
    188         }
    189 
    190         /* if local devie can put all I-PDU in one AGF */
    191         if (max_num_pdu_in_agf <= remote_rw)
    192         {
    193             efficent_miu = (remote_link_miu - max_num_pdu_in_agf*5)/max_num_pdu_in_agf;
    194         }
    195         else
    196         {
    197             efficent_miu = remote_miu;
    198         }
    199     }
    200     else
    201     {
    202         efficent_miu = remote_miu;
    203     }
    204 
    205     SNEP_TRACE_DEBUG2 ("nfa_snep_get_efficent_miu () remote_link_miu = %d, efficent_miu = %d",
    206                         remote_link_miu, efficent_miu);
    207 
    208     return efficent_miu;
    209 }
    210 
    211 /*******************************************************************************
    212 **
    213 ** Function         nfa_snep_check_version
    214 **
    215 ** Description      Check version of SNEP
    216 **
    217 **
    218 ** Returns          TRUE if supported
    219 **
    220 *******************************************************************************/
    221 BOOLEAN nfa_snep_check_version (UINT8 version)
    222 {
    223     /* if major version is matched */
    224     if ((version & 0xF0) == (NFA_SNEP_VERSION & 0xF0))
    225         return TRUE;
    226     else
    227         return FALSE;
    228 }
    229 
    230 /*******************************************************************************
    231 **
    232 ** Function         nfa_snep_send_msg
    233 **
    234 ** Description      Send complete or the first fragment of SNEP message with or
    235 **                  without information.
    236 **
    237 ** Returns          void
    238 **
    239 *******************************************************************************/
    240 void nfa_snep_send_msg (UINT8 opcode, UINT8 dlink)
    241 {
    242     BT_HDR *p_msg;
    243     UINT32 length;
    244     UINT8  *p;
    245     tLLCP_STATUS status = LLCP_STATUS_FAIL;
    246 
    247 #if (BT_TRACE_VERBOSE == TRUE)
    248     SNEP_TRACE_DEBUG4 ("nfa_snep_send_msg () [0x%x, 0x%x]: %s (0x%02x)",
    249                        nfa_snep_cb.conn[dlink].local_sap,
    250                        nfa_snep_cb.conn[dlink].remote_sap,
    251                        nfa_snep_opcode (opcode), opcode);
    252 #else
    253     SNEP_TRACE_DEBUG3 ("nfa_snep_send_msg () [0x%x, 0x%x]: opcode 0x%02x",
    254                        nfa_snep_cb.conn[dlink].local_sap,
    255                        nfa_snep_cb.conn[dlink].remote_sap,
    256                        opcode);
    257 #endif
    258 
    259     /* if there is pending SNEP message and opcode can have information */
    260     if (  (nfa_snep_cb.conn[dlink].p_ndef_buff)
    261         &&((opcode == NFA_SNEP_REQ_CODE_GET) || (opcode == NFA_SNEP_REQ_CODE_PUT) || (opcode == NFA_SNEP_RESP_CODE_SUCCESS))  )
    262     {
    263         length = NFA_SNEP_HEADER_SIZE + nfa_snep_cb.conn[dlink].ndef_length;
    264 
    265         if (opcode == NFA_SNEP_REQ_CODE_GET)
    266         {
    267             length += NFA_SNEP_ACCEPT_LEN_SIZE; /* add acceptable length field */
    268         }
    269 
    270         /* if message is bigger than peer's MIU, send the first fragment */
    271         if (length > nfa_snep_cb.conn[dlink].tx_miu)
    272         {
    273             length = nfa_snep_cb.conn[dlink].tx_miu;
    274         }
    275 
    276         if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
    277         {
    278             p_msg->len    = (UINT16) length;
    279             p_msg->offset = LLCP_MIN_OFFSET;
    280 
    281             p = (UINT8*) (p_msg + 1) + p_msg->offset;
    282 
    283             /* add SNEP header */
    284             UINT8_TO_BE_STREAM (p, NFA_SNEP_VERSION);
    285             UINT8_TO_BE_STREAM (p, opcode);
    286 
    287             if (opcode == NFA_SNEP_REQ_CODE_GET)
    288             {
    289                 /* add acceptable length field in information field*/
    290                 UINT32_TO_BE_STREAM (p, nfa_snep_cb.conn[dlink].ndef_length + NFA_SNEP_ACCEPT_LEN_SIZE);
    291                 UINT32_TO_BE_STREAM (p, nfa_snep_cb.conn[dlink].acceptable_length);
    292                 length -= NFA_SNEP_ACCEPT_LEN_SIZE;
    293             }
    294             else
    295             {
    296                 UINT32_TO_BE_STREAM (p, nfa_snep_cb.conn[dlink].ndef_length);
    297             }
    298 
    299             length -= NFA_SNEP_HEADER_SIZE;
    300 
    301 
    302             /* add the first fragment or complete of NDEF message */
    303             memcpy (p, nfa_snep_cb.conn[dlink].p_ndef_buff, length);
    304 
    305 #if (BT_TRACE_PROTOCOL == TRUE)
    306             DispSNEP (nfa_snep_cb.conn[dlink].local_sap,
    307                       nfa_snep_cb.conn[dlink].remote_sap,
    308                      (UINT8*)(p_msg + 1) + p_msg->offset,
    309                       NFA_SNEP_HEADER_SIZE,
    310                       FALSE);
    311 #endif
    312             status = LLCP_SendData (nfa_snep_cb.conn[dlink].local_sap,
    313                                     nfa_snep_cb.conn[dlink].remote_sap, p_msg);
    314 
    315             if (status != LLCP_STATUS_FAIL)
    316             {
    317                 SNEP_TRACE_DEBUG2 ("nfa_snep_send_msg (): sending %d out of %d",
    318                                    length, nfa_snep_cb.conn[dlink].ndef_length);
    319 
    320                 /* if sent complete SNEP message */
    321                 if (length == nfa_snep_cb.conn[dlink].ndef_length)
    322                 {
    323                     nfa_snep_cb.conn[dlink].cur_length = 0;
    324 
    325                     if (  (opcode == NFA_SNEP_RESP_CODE_SUCCESS)
    326                         &&(nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_GET)  )
    327                     {
    328                         /* Set LLCP to send LLCP_SAP_EVT_TX_COMPLETE */
    329                         LLCP_SetTxCompleteNtf (nfa_snep_cb.conn[dlink].local_sap,
    330                                                nfa_snep_cb.conn[dlink].remote_sap);
    331                     }
    332                 }
    333                 else
    334                 {
    335                     /* update sent length */
    336                     nfa_snep_cb.conn[dlink].cur_length = length;
    337 
    338                     if ((opcode == NFA_SNEP_REQ_CODE_GET) || (opcode == NFA_SNEP_REQ_CODE_PUT))
    339                     {
    340                         nfa_snep_cb.conn[dlink].flags |= NFA_SNEP_FLAG_W4_RESP_CONTINUE;
    341                     }
    342                     else /* (opcode == NFA_SNEP_RESP_CODE_SUCCESS) */
    343                     {
    344                         nfa_snep_cb.conn[dlink].flags |= NFA_SNEP_FLAG_W4_REQ_CONTINUE;
    345                     }
    346                 }
    347             }
    348         }
    349     }
    350     else /* opcode without information */
    351     {
    352         if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
    353         {
    354             p_msg->len    = NFA_SNEP_HEADER_SIZE;
    355             p_msg->offset = LLCP_MIN_OFFSET;
    356 
    357             p = (UINT8*) (p_msg + 1) + p_msg->offset;
    358 
    359             /* add SNEP header without information */
    360             UINT8_TO_BE_STREAM (p, NFA_SNEP_VERSION);
    361             UINT8_TO_BE_STREAM (p, opcode);
    362             UINT32_TO_BE_STREAM (p, 0);
    363 
    364 #if (BT_TRACE_PROTOCOL == TRUE)
    365             DispSNEP(nfa_snep_cb.conn[dlink].local_sap,
    366                      nfa_snep_cb.conn[dlink].remote_sap,
    367                      (UINT8*)(p_msg + 1) + p_msg->offset,
    368                      NFA_SNEP_HEADER_SIZE,
    369                      FALSE);
    370 #endif
    371             status = LLCP_SendData (nfa_snep_cb.conn[dlink].local_sap,
    372                                     nfa_snep_cb.conn[dlink].remote_sap, p_msg);
    373         }
    374     }
    375 
    376     if (status == LLCP_STATUS_FAIL)
    377     {
    378         SNEP_TRACE_ERROR0 ("Cannot allocate buffer or failed to send data");
    379 
    380         /* upper layer will free buffer when NFA_SNEP_DISC_EVT is received */
    381         nfa_snep_cb.conn[dlink].p_ndef_buff = 0;
    382 
    383         LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    384                             nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    385     }
    386     else if (status == LLCP_STATUS_CONGESTED)
    387     {
    388         nfa_snep_cb.conn[dlink].congest = TRUE;
    389     }
    390 }
    391 
    392 /*******************************************************************************
    393 **
    394 ** Function         nfa_snep_send_remaining
    395 **
    396 ** Description      Send remaining fragments of SNEP message
    397 **
    398 **
    399 ** Returns          void
    400 **
    401 *******************************************************************************/
    402 void nfa_snep_send_remaining (UINT8 dlink)
    403 {
    404     BT_HDR *p_msg;
    405     UINT8  *p_src, *p_dst;
    406     UINT32 length;
    407     tLLCP_STATUS status;
    408 
    409     SNEP_TRACE_DEBUG1 ("nfa_snep_send_remaining (): dlink:0x%02X", dlink);
    410 
    411     /* while data link connection is not congested */
    412     while (  (nfa_snep_cb.conn[dlink].congest == FALSE)
    413            &&(nfa_snep_cb.conn[dlink].cur_length > 0)   /* if any fragment was sent */
    414            &&(nfa_snep_cb.conn[dlink].cur_length < nfa_snep_cb.conn[dlink].ndef_length)  )
    415     {
    416         /* start of remaining fragments */
    417         p_src = nfa_snep_cb.conn[dlink].p_ndef_buff + nfa_snep_cb.conn[dlink].cur_length;
    418 
    419         length = nfa_snep_cb.conn[dlink].ndef_length - nfa_snep_cb.conn[dlink].cur_length;
    420 
    421         /* sending up to peer's MIU */
    422         if (length > nfa_snep_cb.conn[dlink].tx_miu)
    423         {
    424             length = nfa_snep_cb.conn[dlink].tx_miu;
    425         }
    426 
    427         status = LLCP_STATUS_FAIL;
    428 
    429         if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
    430         {
    431             p_msg->len    = (UINT16) length;
    432             p_msg->offset = LLCP_MIN_OFFSET;
    433 
    434             p_dst = (UINT8*) (p_msg + 1) + p_msg->offset;
    435 
    436             memcpy (p_dst, p_src, length);
    437 
    438             status = LLCP_SendData (nfa_snep_cb.conn[dlink].local_sap,
    439                                     nfa_snep_cb.conn[dlink].remote_sap, p_msg);
    440 
    441             if (status != LLCP_STATUS_FAIL)
    442             {
    443                 /* update sent length */
    444                 nfa_snep_cb.conn[dlink].cur_length += length;
    445 
    446                 SNEP_TRACE_DEBUG2 ("nfa_snep_send_remaining (): sending %d out of %d",
    447                                    nfa_snep_cb.conn[dlink].cur_length,
    448                                    nfa_snep_cb.conn[dlink].ndef_length);
    449 
    450                 /* if sent the last fragment */
    451                 if (nfa_snep_cb.conn[dlink].cur_length == nfa_snep_cb.conn[dlink].ndef_length)
    452                 {
    453                     nfa_snep_cb.conn[dlink].cur_length = 0;
    454 
    455                     if (  (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_RESP_CODE_SUCCESS)
    456                         &&(nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_CONTINUE)  )
    457                     {
    458                         /* Set LLCP to send LLCP_SAP_EVT_TX_COMPLETE */
    459                         LLCP_SetTxCompleteNtf (nfa_snep_cb.conn[dlink].local_sap,
    460                                                nfa_snep_cb.conn[dlink].remote_sap);
    461                     }
    462                 }
    463             }
    464         }
    465 
    466         if (status == LLCP_STATUS_CONGESTED)
    467         {
    468             nfa_snep_cb.conn[dlink].congest = TRUE;
    469 
    470             /* wait for uncongested event from LLCP */
    471             break;
    472         }
    473         else if (status == LLCP_STATUS_FAIL)
    474         {
    475             SNEP_TRACE_ERROR0 ("Cannot allocate buffer or failed to send data");
    476 
    477             /* upper layer will free buffer when NFA_SNEP_DISC_EVT is received */
    478             nfa_snep_cb.conn[dlink].p_ndef_buff = 0;
    479 
    480             LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    481                                 nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    482             return;
    483         }
    484     }
    485 }
    486 
    487 /*******************************************************************************
    488 **
    489 ** Function         nfa_snep_llcp_cback
    490 **
    491 ** Description      Processing event from LLCP
    492 **
    493 **
    494 ** Returns          None
    495 **
    496 *******************************************************************************/
    497 void nfa_snep_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data)
    498 {
    499     SNEP_TRACE_DEBUG2 ("nfa_snep_llcp_cback (): event:0x%02X, local_sap:0x%02X", p_data->hdr.event, p_data->hdr.local_sap);
    500 
    501     switch (p_data->hdr.event)
    502     {
    503     case LLCP_SAP_EVT_DATA_IND:
    504         nfa_snep_proc_llcp_data_ind (p_data);
    505         break;
    506 
    507     case LLCP_SAP_EVT_CONNECT_IND:
    508         nfa_snep_proc_llcp_connect_ind (p_data);
    509         break;
    510 
    511     case LLCP_SAP_EVT_CONNECT_RESP:
    512         nfa_snep_proc_llcp_connect_resp (p_data);
    513         break;
    514 
    515     case LLCP_SAP_EVT_DISCONNECT_IND:
    516         nfa_snep_proc_llcp_disconnect_ind (p_data);
    517         break;
    518 
    519     case LLCP_SAP_EVT_DISCONNECT_RESP:
    520         nfa_snep_proc_llcp_disconnect_resp (p_data);
    521         break;
    522 
    523     case LLCP_SAP_EVT_CONGEST:
    524         /* congestion start/end */
    525         nfa_snep_proc_llcp_congest (p_data);
    526         break;
    527 
    528     case LLCP_SAP_EVT_LINK_STATUS:
    529         nfa_snep_proc_llcp_link_status (p_data);
    530         break;
    531 
    532     case LLCP_SAP_EVT_TX_COMPLETE:
    533         nfa_snep_proc_llcp_tx_complete (p_data);
    534         break;
    535 
    536     default:
    537         SNEP_TRACE_ERROR1 ("Unknown event:0x%02X", p_data->hdr.event);
    538         return;
    539     }
    540 }
    541 
    542 /*******************************************************************************
    543 **
    544 ** Function         nfa_snep_validate_rx_msg
    545 **
    546 ** Description      Validate version, opcode, length in received message
    547 **
    548 **
    549 ** Returns          TRUE if message is valid
    550 **
    551 *******************************************************************************/
    552 BOOLEAN nfa_snep_validate_rx_msg (UINT8 dlink)
    553 {
    554     UINT32  length;
    555     UINT8   buffer[NFA_SNEP_HEADER_SIZE], *p;
    556     BOOLEAN more;
    557     UINT8   version, opcode;
    558     UINT32  info_len;
    559 
    560     SNEP_TRACE_DEBUG0 ("nfa_snep_validate_rx_msg ()");
    561 
    562     more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
    563                                   nfa_snep_cb.conn[dlink].remote_sap,
    564                                   NFA_SNEP_HEADER_SIZE,
    565                                   &length, buffer);
    566 
    567 #if (BT_TRACE_PROTOCOL == TRUE)
    568     DispSNEP(nfa_snep_cb.conn[dlink].local_sap,
    569              nfa_snep_cb.conn[dlink].remote_sap,
    570              buffer,
    571              (UINT16)length,
    572              TRUE);
    573 #endif
    574 
    575     /* check if it has minimum header,
    576     ** the first fragment shall include at least the entier SNEP header
    577     */
    578     if (length < NFA_SNEP_HEADER_SIZE)
    579     {
    580         SNEP_TRACE_ERROR0 ("The first fragment shall include at least the entire SNEP header");
    581 
    582         /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
    583         nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
    584 
    585         LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    586                             nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    587         return FALSE;
    588     }
    589 
    590     p = buffer;
    591 
    592     /* parse SNEP header */
    593     BE_STREAM_TO_UINT8 (version, p);
    594     BE_STREAM_TO_UINT8 (opcode,  p);
    595     BE_STREAM_TO_UINT32 (info_len, p);
    596 
    597     /* check version of SNEP */
    598     if (!nfa_snep_check_version (version))
    599     {
    600         nfa_snep_send_msg (NFA_SNEP_RESP_CODE_UNSUPP_VER, dlink);
    601         return FALSE;
    602     }
    603 
    604     /* check valid opcode for server */
    605     if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_SERVER)
    606     {
    607         /* if this is response message */
    608         if (opcode & NFA_SNEP_RESP_CODE_CONTINUE)
    609         {
    610             SNEP_TRACE_ERROR0 ("Invalid opcode for server");
    611 
    612             /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
    613             nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
    614 
    615             LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    616                                 nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    617             return FALSE;
    618         }
    619         else if (  (opcode != NFA_SNEP_REQ_CODE_CONTINUE)
    620                  &&(opcode != NFA_SNEP_REQ_CODE_GET)
    621                  &&(opcode != NFA_SNEP_REQ_CODE_PUT)
    622                  &&(opcode != NFA_SNEP_REQ_CODE_REJECT)  )
    623         {
    624             SNEP_TRACE_ERROR0 ("Not supported opcode for server");
    625             nfa_snep_send_msg (NFA_SNEP_RESP_CODE_NOT_IMPLM, dlink);
    626             return FALSE;
    627         }
    628     }
    629     /* check valid opcode for client */
    630     else
    631     {
    632         if (  (opcode != NFA_SNEP_RESP_CODE_CONTINUE)
    633             &&(opcode != NFA_SNEP_RESP_CODE_SUCCESS)
    634             &&(opcode != NFA_SNEP_RESP_CODE_NOT_FOUND)
    635             &&(opcode != NFA_SNEP_RESP_CODE_EXCESS_DATA)
    636             &&(opcode != NFA_SNEP_RESP_CODE_BAD_REQ)
    637             &&(opcode != NFA_SNEP_RESP_CODE_NOT_IMPLM)
    638             &&(opcode != NFA_SNEP_RESP_CODE_UNSUPP_VER)
    639             &&(opcode != NFA_SNEP_RESP_CODE_REJECT)  )
    640         {
    641             SNEP_TRACE_ERROR0 ("Invalid opcode for client");
    642             /* client cannot send error code so disconnect */
    643             /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
    644             nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
    645 
    646             LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    647                                 nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    648             return FALSE;
    649         }
    650     }
    651 
    652     if (opcode == NFA_SNEP_REQ_CODE_GET)
    653     {
    654         more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
    655                                       nfa_snep_cb.conn[dlink].remote_sap,
    656                                       NFA_SNEP_ACCEPT_LEN_SIZE,
    657                                       &length, buffer);
    658 
    659         if (length < NFA_SNEP_ACCEPT_LEN_SIZE)
    660         {
    661             /*
    662             ** Including acceptable length in the first segment is not mandated in spec
    663             ** but MIU is always big enough to include acceptable length field.
    664             */
    665             nfa_snep_send_msg (NFA_SNEP_RESP_CODE_BAD_REQ, dlink);
    666             return FALSE;
    667         }
    668 
    669         p = buffer;
    670         BE_STREAM_TO_UINT32 (nfa_snep_cb.conn[dlink].acceptable_length, p);
    671 
    672         /* store expected NDEF message length */
    673         nfa_snep_cb.conn[dlink].ndef_length = info_len - NFA_SNEP_ACCEPT_LEN_SIZE;
    674     }
    675     else if (  (opcode == NFA_SNEP_REQ_CODE_PUT)
    676              ||((opcode == NFA_SNEP_RESP_CODE_SUCCESS) && (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)))
    677     {
    678         /* store expected NDEF message length */
    679         nfa_snep_cb.conn[dlink].ndef_length = info_len;
    680     }
    681     else
    682     {
    683         if (more)
    684         {
    685             SNEP_TRACE_ERROR0 ("The information field shall not be transmitted with this request or response");
    686 
    687             if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_SERVER)
    688             {
    689                 nfa_snep_send_msg (NFA_SNEP_RESP_CODE_BAD_REQ, dlink);
    690             }
    691             /* client cannot send error code so disconnect */
    692             /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
    693             nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
    694 
    695             LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    696                                 nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    697             return FALSE;
    698         }
    699     }
    700 
    701     /* store received opcode */
    702     nfa_snep_cb.conn[dlink].rx_code = opcode;
    703 
    704     return TRUE;
    705 }
    706 
    707 /*******************************************************************************
    708 **
    709 ** Function         nfa_snep_store_first_rx_msg
    710 **
    711 ** Description      Allocate buffer and store the first fragment
    712 **
    713 **
    714 ** Returns          TRUE if the received fragment is successfully stored
    715 **
    716 *******************************************************************************/
    717 BOOLEAN nfa_snep_store_first_rx_msg (UINT8 dlink)
    718 {
    719     tNFA_SNEP_EVT_DATA evt_data;
    720     BOOLEAN            more;
    721     UINT32             length;
    722 
    723     /* send event to upper layer of this data link connection to allocate buffer */
    724     evt_data.alloc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
    725     evt_data.alloc.req_code    = nfa_snep_cb.conn[dlink].rx_code;
    726     evt_data.alloc.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
    727     evt_data.alloc.p_buff      = NULL;
    728 
    729     nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_ALLOC_BUFF_EVT, &evt_data);
    730     nfa_snep_cb.conn[dlink].p_ndef_buff = evt_data.alloc.p_buff;
    731 
    732     /* store information into application buffer */
    733     if (nfa_snep_cb.conn[dlink].p_ndef_buff)
    734     {
    735         /* store buffer size */
    736         nfa_snep_cb.conn[dlink].buff_length = evt_data.alloc.ndef_length;
    737 
    738         more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
    739                                       nfa_snep_cb.conn[dlink].remote_sap,
    740                                       nfa_snep_cb.conn[dlink].buff_length,
    741                                       &length,
    742                                       nfa_snep_cb.conn[dlink].p_ndef_buff);
    743 
    744         /* store received message length */
    745         nfa_snep_cb.conn[dlink].cur_length  = (UINT32) length;
    746 
    747         SNEP_TRACE_DEBUG2 ("Received NDEF on SNEP, %d ouf of %d",
    748                            nfa_snep_cb.conn[dlink].cur_length,
    749                            nfa_snep_cb.conn[dlink].ndef_length);
    750 
    751         /* if fragmented */
    752         if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].cur_length)
    753         {
    754             nfa_snep_cb.conn[dlink].rx_fragments = TRUE;
    755         }
    756         else if (more)
    757         {
    758             /* ignore extra bytes in the message */
    759             length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
    760                                                nfa_snep_cb.conn[dlink].remote_sap);
    761 
    762             SNEP_TRACE_WARNING1 ("Received extra %d bytes on SNEP", length);
    763         }
    764 
    765         return TRUE;
    766     }
    767     else
    768     {
    769         SNEP_TRACE_ERROR1 ("Upper layer cannot allocate buffer for %d bytes",
    770                            nfa_snep_cb.conn[dlink].ndef_length);
    771 
    772         /* clear data in data link connection */
    773         length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
    774                                            nfa_snep_cb.conn[dlink].remote_sap);
    775 
    776         /* if fragmented */
    777         if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].cur_length)
    778         {
    779             /* notify peer not to send any more fragment */
    780             if (evt_data.alloc.resp_code != NFA_SNEP_RESP_CODE_NOT_IMPLM)
    781             {
    782                 /* Set proper code */
    783                 evt_data.alloc.resp_code = NFA_SNEP_REQ_CODE_REJECT;
    784             }
    785         }
    786         else
    787         {
    788             if (evt_data.alloc.resp_code != NFA_SNEP_RESP_CODE_NOT_IMPLM)
    789             {
    790                 /* Set proper code */
    791                 evt_data.alloc.resp_code = NFA_SNEP_RESP_CODE_NOT_FOUND;
    792             }
    793         }
    794 
    795         nfa_snep_send_msg (evt_data.alloc.resp_code, dlink);
    796 
    797         return FALSE;
    798     }
    799 }
    800 
    801 /*******************************************************************************
    802 **
    803 ** Function         nfa_snep_proc_first_rx_msg
    804 **
    805 ** Description      Process the first part of received message
    806 **
    807 **
    808 ** Returns          TRUE if it is not fragmented message
    809 **                  FALSE if it is fragmented or found error
    810 **
    811 *******************************************************************************/
    812 BOOLEAN nfa_snep_proc_first_rx_msg (UINT8 dlink)
    813 {
    814     UINT32             length;
    815     tNFA_SNEP_EVT_DATA evt_data;
    816     BOOLEAN            more;
    817 
    818     SNEP_TRACE_DEBUG0 ("nfa_snep_proc_first_rx_msg ()");
    819 
    820     /* if version, opcode or length is not valid in received message */
    821     if (!nfa_snep_validate_rx_msg (dlink))
    822     {
    823         /* clear data in data link connection */
    824         LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
    825                                   nfa_snep_cb.conn[dlink].remote_sap);
    826         return FALSE;
    827     }
    828 
    829     if (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_GET)
    830     {
    831         /* if failed to allocate buffer */
    832         if (!nfa_snep_store_first_rx_msg (dlink))
    833         {
    834             return FALSE;
    835         }
    836         else
    837         {
    838             if (nfa_snep_cb.conn[dlink].rx_fragments == TRUE)
    839             {
    840                 /* let peer send remaining fragments */
    841                 nfa_snep_send_msg (NFA_SNEP_RESP_CODE_CONTINUE, dlink);
    842 
    843                 return FALSE;
    844             }
    845         }
    846     }
    847     else if (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_PUT)
    848     {
    849         /* if failed to allocate buffer */
    850         if (!nfa_snep_store_first_rx_msg (dlink))
    851         {
    852             return FALSE;
    853         }
    854         else
    855         {
    856             if (nfa_snep_cb.conn[dlink].rx_fragments == TRUE)
    857             {
    858                 /* let peer send remaining fragments */
    859                 nfa_snep_send_msg (NFA_SNEP_RESP_CODE_CONTINUE, dlink);
    860                 return FALSE;
    861             }
    862         }
    863     }
    864     /* if we got response of GET request from server */
    865     else if (  (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_RESP_CODE_SUCCESS)
    866              &&(nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)  )
    867     {
    868         /* if server is sending more than acceptable length */
    869         if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].acceptable_length)
    870         {
    871             SNEP_TRACE_ERROR0 ("Server is sending more than acceptable length");
    872 
    873             length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
    874                                                nfa_snep_cb.conn[dlink].remote_sap);
    875 
    876             /* if fragmented */
    877             if (nfa_snep_cb.conn[dlink].ndef_length > length)
    878             {
    879                 nfa_snep_send_msg (NFA_SNEP_REQ_CODE_REJECT, dlink);
    880                 nfa_snep_cb.conn[dlink].rx_fragments = FALSE;
    881             }
    882 
    883             /* return error to client so buffer can be freed */
    884             evt_data.get_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
    885             evt_data.get_resp.resp_code   = NFA_SNEP_RESP_CODE_EXCESS_DATA;
    886             evt_data.get_resp.ndef_length = 0;
    887             evt_data.get_resp.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
    888 
    889             nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_EVT, &evt_data);
    890             nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
    891 
    892             return FALSE;
    893         }
    894 
    895         more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
    896                                       nfa_snep_cb.conn[dlink].remote_sap,
    897                                       nfa_snep_cb.conn[dlink].buff_length,
    898                                       &length,
    899                                       nfa_snep_cb.conn[dlink].p_ndef_buff);
    900 
    901         /* store received message length */
    902         nfa_snep_cb.conn[dlink].cur_length = length;
    903 
    904         SNEP_TRACE_DEBUG2 ("Received NDEF on SNEP, %d ouf of %d",
    905                            nfa_snep_cb.conn[dlink].cur_length,
    906                            nfa_snep_cb.conn[dlink].ndef_length);
    907 
    908         if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].cur_length)
    909         {
    910             nfa_snep_cb.conn[dlink].rx_fragments = TRUE;
    911         }
    912         else if (more)
    913         {
    914             /* ignore extra bytes in the message */
    915             length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
    916                                                nfa_snep_cb.conn[dlink].remote_sap);
    917 
    918             SNEP_TRACE_WARNING1 ("Received extra %d bytes on SNEP", length);
    919         }
    920 
    921         if (nfa_snep_cb.conn[dlink].rx_fragments == TRUE)
    922         {
    923             /* let peer send remaining fragments */
    924             nfa_snep_send_msg (NFA_SNEP_REQ_CODE_CONTINUE, dlink);
    925 
    926             /* start timer for next fragment */
    927             nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
    928 
    929             return FALSE;
    930         }
    931     }
    932 
    933     /* other than above cases, there is no inforamtion field */
    934 
    935     return TRUE;
    936 }
    937 
    938 /*******************************************************************************
    939 **
    940 ** Function         nfa_snep_assemble_fragments
    941 **
    942 ** Description      Assemble fragments of SNEP message
    943 **
    944 **
    945 ** Returns          TRUE if it is not fragmented message
    946 **                  FALSE if it is fragmented or found error
    947 **
    948 *******************************************************************************/
    949 BOOLEAN nfa_snep_assemble_fragments (UINT8 dlink)
    950 {
    951     BOOLEAN more;
    952     UINT32  length;
    953 
    954     more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
    955                                   nfa_snep_cb.conn[dlink].remote_sap,
    956                                   nfa_snep_cb.conn[dlink].buff_length - nfa_snep_cb.conn[dlink].cur_length,
    957                                   &length,
    958                                   nfa_snep_cb.conn[dlink].p_ndef_buff + nfa_snep_cb.conn[dlink].cur_length);
    959 
    960     nfa_snep_cb.conn[dlink].cur_length += length;
    961 
    962     SNEP_TRACE_DEBUG2 ("Received NDEF on SNEP, %d ouf of %d",
    963                        nfa_snep_cb.conn[dlink].cur_length,
    964                        nfa_snep_cb.conn[dlink].ndef_length);
    965 
    966     /* if received the last fragment */
    967     if (nfa_snep_cb.conn[dlink].ndef_length == nfa_snep_cb.conn[dlink].cur_length)
    968     {
    969         nfa_snep_cb.conn[dlink].rx_fragments = FALSE;
    970 
    971         if (more)
    972         {
    973             length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
    974                                                nfa_snep_cb.conn[dlink].remote_sap);
    975 
    976             SNEP_TRACE_ERROR2 ("Received extra %d bytes more than NDEF length (%d)",
    977                                length,
    978                                nfa_snep_cb.conn[dlink].ndef_length);
    979 
    980             /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
    981             nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
    982 
    983             LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
    984                                 nfa_snep_cb.conn[dlink].remote_sap, TRUE);
    985 
    986             return FALSE;
    987         }
    988     }
    989     else
    990     {
    991         if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CLIENT)
    992         {
    993             /* wait for more fragments */
    994             nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
    995         }
    996 
    997         return FALSE;
    998     }
    999 
   1000     return TRUE;
   1001 }
   1002 
   1003 /*******************************************************************************
   1004 **
   1005 ** Function         nfa_snep_proc_llcp_data_ind
   1006 **
   1007 ** Description      Processing incoming data from LLCP
   1008 **
   1009 **
   1010 ** Returns          None
   1011 **
   1012 *******************************************************************************/
   1013 void nfa_snep_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA  *p_data)
   1014 {
   1015     UINT8              dlink;
   1016     tNFA_SNEP_EVT_DATA evt_data;
   1017 
   1018     SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_data_ind ()");
   1019 
   1020     /* find connection control block with SAP */
   1021     dlink = nfa_snep_sap_to_index (p_data->data_ind.local_sap,
   1022                                    p_data->data_ind.remote_sap,
   1023                                    NFA_SNEP_FLAG_ANY);
   1024 
   1025     /* if found */
   1026     if (  (dlink < NFA_SNEP_MAX_CONN)
   1027         &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
   1028     {
   1029         if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CLIENT)
   1030         {
   1031             /* stop timer for response from server */
   1032             nfa_sys_stop_timer (&nfa_snep_cb.conn[dlink].timer);
   1033         }
   1034 
   1035         /* if received the first fragment or complete SNEP message */
   1036         if (nfa_snep_cb.conn[dlink].rx_fragments == FALSE)
   1037         {
   1038             if (!nfa_snep_proc_first_rx_msg (dlink))
   1039             {
   1040                 /* need more data or found error */
   1041                 return;
   1042             }
   1043         }
   1044         /* if received other than the first fragment */
   1045         else
   1046         {
   1047             if (!nfa_snep_assemble_fragments (dlink))
   1048             {
   1049                 /* need more data or found error */
   1050                 return;
   1051             }
   1052         }
   1053 
   1054         /* processing complete SNEP message */
   1055         switch (nfa_snep_cb.conn[dlink].rx_code)
   1056         {
   1057         case NFA_SNEP_REQ_CODE_CONTINUE:
   1058             if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_W4_REQ_CONTINUE)
   1059             {
   1060                 nfa_snep_cb.conn[dlink].flags &= ~NFA_SNEP_FLAG_W4_REQ_CONTINUE;
   1061 
   1062                 /* send remaining fragments of GET response */
   1063                 nfa_snep_send_remaining (dlink);
   1064             }
   1065             else
   1066             {
   1067                 SNEP_TRACE_ERROR0 ("Received invalid NFA_SNEP_REQ_CODE_CONTINUE");
   1068 
   1069                 /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
   1070                 nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
   1071 
   1072                 LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
   1073                                     nfa_snep_cb.conn[dlink].remote_sap, TRUE);
   1074             }
   1075             break;
   1076 
   1077         case NFA_SNEP_REQ_CODE_GET:
   1078             evt_data.get_req.conn_handle       = (NFA_HANDLE_GROUP_SNEP | dlink);
   1079             evt_data.get_req.acceptable_length = nfa_snep_cb.conn[dlink].acceptable_length;
   1080 
   1081             /* NDEF message */
   1082             evt_data.get_req.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
   1083             evt_data.get_req.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
   1084 
   1085             nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
   1086 
   1087             /* send event to server of this data link connection */
   1088             nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_REQ_EVT, &evt_data);
   1089             break;
   1090 
   1091         case NFA_SNEP_REQ_CODE_PUT:
   1092             evt_data.put_req.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1093 
   1094             /* NDEF message */
   1095             evt_data.put_req.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
   1096             evt_data.put_req.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
   1097 
   1098             nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
   1099 
   1100             /* send event to server of this data link connection */
   1101             nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_PUT_REQ_EVT, &evt_data);
   1102             break;
   1103 
   1104         case NFA_SNEP_RESP_CODE_CONTINUE:
   1105             if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_W4_RESP_CONTINUE)
   1106             {
   1107                 nfa_snep_cb.conn[dlink].flags &= ~NFA_SNEP_FLAG_W4_RESP_CONTINUE;
   1108                 /* send remaining fragments GET/PUT request */
   1109                 nfa_snep_send_remaining (dlink);
   1110             }
   1111             else
   1112             {
   1113                 SNEP_TRACE_ERROR0 ("Received invalid NFA_SNEP_RESP_CODE_CONTINUE");
   1114 
   1115                 /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
   1116                 nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
   1117 
   1118                 LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
   1119                                     nfa_snep_cb.conn[dlink].remote_sap, TRUE);
   1120             }
   1121             break;
   1122 
   1123         case NFA_SNEP_RESP_CODE_SUCCESS:
   1124             if (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)
   1125             {
   1126                 evt_data.get_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1127                 evt_data.get_resp.resp_code   = NFA_SNEP_RESP_CODE_SUCCESS;
   1128                 evt_data.get_resp.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
   1129                 evt_data.get_resp.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
   1130 
   1131                 nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
   1132 
   1133                 /* send event to client of this data link connection */
   1134                 nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_EVT, &evt_data);
   1135             }
   1136             else
   1137             {
   1138                 evt_data.put_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1139                 evt_data.put_resp.resp_code   = NFA_SNEP_RESP_CODE_SUCCESS;
   1140 
   1141                 /* send event to client of this data link connection */
   1142                 nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_PUT_RESP_EVT, &evt_data);
   1143             }
   1144             break;
   1145 
   1146         case NFA_SNEP_RESP_CODE_NOT_FOUND:
   1147         case NFA_SNEP_RESP_CODE_EXCESS_DATA:
   1148         case NFA_SNEP_RESP_CODE_BAD_REQ:
   1149         case NFA_SNEP_RESP_CODE_NOT_IMPLM:
   1150         case NFA_SNEP_RESP_CODE_UNSUPP_VER:
   1151         case NFA_SNEP_RESP_CODE_REJECT:
   1152             /* if client sent GET request */
   1153             if (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)
   1154             {
   1155                 evt_data.get_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1156                 evt_data.get_resp.resp_code   = nfa_snep_cb.conn[dlink].rx_code;
   1157                 evt_data.get_resp.ndef_length = 0;
   1158                 evt_data.get_resp.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
   1159 
   1160                 /* send event to client of this data link connection */
   1161                 nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_EVT, &evt_data);
   1162             }
   1163             /* if client sent PUT request */
   1164             else if (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_PUT)
   1165             {
   1166                 evt_data.put_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1167                 evt_data.put_resp.resp_code   = nfa_snep_cb.conn[dlink].rx_code;
   1168 
   1169                 /* send event to client of this data link connection */
   1170                 nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_PUT_RESP_EVT, &evt_data);
   1171             }
   1172 
   1173             /* if there is remaining SNEP message */
   1174             if (nfa_snep_cb.conn[dlink].p_ndef_buff)
   1175             {
   1176                 nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
   1177             }
   1178             break;
   1179         }
   1180     }
   1181 }
   1182 
   1183 /*******************************************************************************
   1184 **
   1185 ** Function         nfa_snep_proc_llcp_connect_ind
   1186 **
   1187 ** Description      Processing connection request from peer
   1188 **
   1189 **
   1190 ** Returns          None
   1191 **
   1192 *******************************************************************************/
   1193 void nfa_snep_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
   1194 {
   1195     UINT8 server, dlink;
   1196     tLLCP_CONNECTION_PARAMS params;
   1197     tNFA_SNEP_EVT_DATA      evt_data;
   1198 
   1199     SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_connect_ind ()");
   1200 
   1201     server = nfa_snep_sap_to_index (p_data->connect_ind.server_sap,
   1202                                     NFA_SNEP_ANY_SAP,
   1203                                     NFA_SNEP_FLAG_SERVER);
   1204 
   1205     /* if found valid server */
   1206     if (server < NFA_SNEP_MAX_CONN)
   1207     {
   1208         /* allocate connection control block for data link connection */
   1209         dlink = nfa_snep_allocate_cb ();
   1210 
   1211         if (dlink < NFA_SNEP_MAX_CONN)
   1212         {
   1213             /* set data link connection's callback to server's callback */
   1214             /* request will be sent to this server */
   1215             nfa_snep_cb.conn[dlink].local_sap  = p_data->connect_ind.local_sap;
   1216             nfa_snep_cb.conn[dlink].remote_sap = p_data->connect_ind.remote_sap;
   1217             nfa_snep_cb.conn[dlink].p_cback    = nfa_snep_cb.conn[server].p_cback;
   1218             nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CONNECTED;
   1219 
   1220             nfa_snep_cb.conn[dlink].tx_miu = nfa_snep_get_efficent_miu (p_data->connect_ind.miu,
   1221                                                                         p_data->connect_ind.rw);
   1222 
   1223             /* accept connection request */
   1224             params.miu = NFA_SNEP_MIU;
   1225             params.rw  = NFA_SNEP_RW;
   1226             params.sn[0] = 0;
   1227 
   1228             LLCP_ConnectCfm (p_data->connect_ind.local_sap,
   1229                              p_data->connect_ind.remote_sap, &params);
   1230 
   1231             evt_data.connect.reg_handle  = (NFA_HANDLE_GROUP_SNEP | server);
   1232             evt_data.connect.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1233             nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_CONNECTED_EVT, &evt_data);
   1234         }
   1235         else
   1236         {
   1237             SNEP_TRACE_ERROR0 ("Cannot allocate connection control block");
   1238             LLCP_ConnectReject (p_data->connect_ind.local_sap,
   1239                                 p_data->connect_ind.remote_sap,
   1240                                 LLCP_SAP_DM_REASON_TEMP_REJECT_THIS);
   1241         }
   1242     }
   1243     else
   1244     {
   1245         SNEP_TRACE_ERROR0 ("Cannot find SNEP server");
   1246         LLCP_ConnectReject (p_data->connect_ind.local_sap,
   1247                             p_data->connect_ind.remote_sap,
   1248                             LLCP_SAP_DM_REASON_NO_SERVICE);
   1249     }
   1250 }
   1251 
   1252 /*******************************************************************************
   1253 **
   1254 ** Function         nfa_snep_proc_llcp_connect_resp
   1255 **
   1256 ** Description      Processing connection response from peer
   1257 **
   1258 **
   1259 ** Returns          None
   1260 **
   1261 *******************************************************************************/
   1262 void nfa_snep_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
   1263 {
   1264     UINT8 dlink;
   1265     tNFA_SNEP_EVT_DATA evt_data;
   1266 
   1267     SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_connect_resp ()");
   1268 
   1269     /* find client by SAP */
   1270     dlink = nfa_snep_sap_to_index (p_data->connect_resp.local_sap,
   1271                                    NFA_SNEP_ANY_SAP,
   1272                                    NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTING);
   1273 
   1274     /* if found client */
   1275     if (dlink < NFA_SNEP_MAX_CONN)
   1276     {
   1277         nfa_snep_cb.conn[dlink].remote_sap = p_data->connect_resp.remote_sap;
   1278         nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTED;
   1279 
   1280         nfa_snep_cb.conn[dlink].tx_miu = nfa_snep_get_efficent_miu (p_data->connect_resp.miu,
   1281                                                                     p_data->connect_resp.rw);
   1282 
   1283         evt_data.connect.reg_handle  = (NFA_HANDLE_GROUP_SNEP | dlink);
   1284         evt_data.connect.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1285         nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_CONNECTED_EVT, &evt_data);
   1286     }
   1287     else
   1288     {
   1289         SNEP_TRACE_ERROR0 ("Cannot find SNEP client");
   1290         LLCP_DisconnectReq (p_data->connect_resp.local_sap,
   1291                             p_data->connect_resp.remote_sap, TRUE);
   1292     }
   1293 }
   1294 
   1295 /*******************************************************************************
   1296 **
   1297 ** Function         nfa_snep_proc_llcp_disconnect_ind
   1298 **
   1299 ** Description      Processing disconnection request from peer
   1300 **
   1301 **
   1302 ** Returns          None
   1303 **
   1304 *******************************************************************************/
   1305 void nfa_snep_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
   1306 {
   1307     UINT8              dlink;
   1308     tNFA_SNEP_EVT_DATA evt_data;
   1309 
   1310     SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_disconnect_ind ()");
   1311 
   1312     /* find connection control block by SAP */
   1313     dlink = nfa_snep_sap_to_index (p_data->disconnect_ind.local_sap,
   1314                                    p_data->disconnect_ind.remote_sap,
   1315                                    NFA_SNEP_FLAG_ANY);
   1316 
   1317     /* if found */
   1318     if (dlink < NFA_SNEP_MAX_CONN)
   1319     {
   1320         evt_data.disc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1321 
   1322         nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_DISC_EVT, &evt_data);
   1323 
   1324         if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CLIENT)
   1325         {
   1326             /* clear other flags */
   1327             nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_CLIENT;
   1328             nfa_snep_cb.conn[dlink].remote_sap = LLCP_INVALID_SAP;
   1329         }
   1330         else
   1331         {
   1332             nfa_snep_deallocate_cb (dlink);
   1333         }
   1334     }
   1335     else
   1336     {
   1337         SNEP_TRACE_ERROR0 ("Cannot find SNEP connection");
   1338     }
   1339 }
   1340 
   1341 /*******************************************************************************
   1342 **
   1343 ** Function         nfa_snep_proc_llcp_disconnect_resp
   1344 **
   1345 ** Description      Processing rejected connection from peer
   1346 **
   1347 **
   1348 ** Returns          None
   1349 **
   1350 *******************************************************************************/
   1351 void nfa_snep_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
   1352 {
   1353     UINT8              dlink, flags;
   1354     UINT8              remote_sap;
   1355     tNFA_SNEP_EVT_DATA evt_data;
   1356 
   1357     SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_disconnect_resp ()");
   1358 
   1359     /* if remote sent response to disconnection requested by local */
   1360     if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_RESP_DISC)
   1361     {
   1362         remote_sap = p_data->disconnect_resp.remote_sap;
   1363         flags      = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTED;
   1364     }
   1365     else /* connection failed so we don't have remote SAP */
   1366     {
   1367         remote_sap = NFA_SNEP_ANY_SAP;
   1368         flags      = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTING;
   1369     }
   1370 
   1371     /* find connection control block by SAP */
   1372     dlink = nfa_snep_sap_to_index (p_data->disconnect_resp.local_sap,
   1373                                    remote_sap,
   1374                                    flags);
   1375 
   1376     /* if found client */
   1377     if (dlink < NFA_SNEP_MAX_CONN)
   1378     {
   1379         evt_data.disc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1380 
   1381         nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_DISC_EVT, &evt_data);
   1382 
   1383         /* clear other flags */
   1384         nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_CLIENT;
   1385         nfa_snep_cb.conn[dlink].remote_sap = LLCP_INVALID_SAP;
   1386     }
   1387     else
   1388     {
   1389         /* find server connection control block by SAP */
   1390         dlink = nfa_snep_sap_to_index (p_data->disconnect_resp.local_sap,
   1391                                        remote_sap,
   1392                                        NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CONNECTED);
   1393 
   1394         /* if found server connection */
   1395         if (dlink < NFA_SNEP_MAX_CONN)
   1396         {
   1397             evt_data.disc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1398 
   1399             nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_DISC_EVT, &evt_data);
   1400 
   1401             nfa_snep_deallocate_cb (dlink);
   1402         }
   1403         else
   1404         {
   1405             SNEP_TRACE_ERROR0 ("Cannot find SNEP connection");
   1406         }
   1407     }
   1408 }
   1409 
   1410 /*******************************************************************************
   1411 **
   1412 ** Function         nfa_snep_proc_llcp_congest
   1413 **
   1414 ** Description      Processing LLCP congestion event
   1415 **
   1416 **
   1417 ** Returns          None
   1418 **
   1419 *******************************************************************************/
   1420 void nfa_snep_proc_llcp_congest (tLLCP_SAP_CBACK_DATA  *p_data)
   1421 {
   1422     UINT8 dlink;
   1423 
   1424     SNEP_TRACE_DEBUG3 ("nfa_snep_proc_llcp_congest () local_sap=0x%x, remote_sap=0x%x, is_congested=%d",
   1425                        p_data->congest.local_sap,
   1426                        p_data->congest.remote_sap,
   1427                        p_data->congest.is_congested);
   1428 
   1429     /* if data link connection is congested */
   1430     if (p_data->congest.link_type == LLCP_LINK_TYPE_DATA_LINK_CONNECTION)
   1431     {
   1432         dlink = nfa_snep_sap_to_index (p_data->congest.local_sap,
   1433                                        p_data->congest.remote_sap,
   1434                                        NFA_SNEP_FLAG_ANY);
   1435 
   1436         if (  (dlink < NFA_SNEP_MAX_CONN)
   1437             &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
   1438         {
   1439             nfa_snep_cb.conn[dlink].congest = p_data->congest.is_congested;
   1440 
   1441             if (!nfa_snep_cb.conn[dlink].congest)
   1442             {
   1443                 /* if received CONTINUE then continue to send remaining fragments */
   1444                 if (  (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_CONTINUE)
   1445                     ||(nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_RESP_CODE_CONTINUE)  )
   1446                 {
   1447                     nfa_snep_send_remaining (dlink);
   1448                 }
   1449             }
   1450         }
   1451     }
   1452 }
   1453 
   1454 /*******************************************************************************
   1455 **
   1456 ** Function         nfa_snep_proc_llcp_link_status
   1457 **
   1458 ** Description      Processing LLCP link status
   1459 **
   1460 **
   1461 ** Returns          none
   1462 **
   1463 *******************************************************************************/
   1464 void nfa_snep_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA  *p_data)
   1465 {
   1466     UINT8              xx;
   1467     tNFA_SNEP_EVT_DATA evt_data;
   1468 
   1469     SNEP_TRACE_DEBUG1 ("nfa_snep_proc_llcp_link_status () is_activated:%d",
   1470                        p_data->link_status.is_activated);
   1471 
   1472     xx = nfa_snep_sap_to_index (p_data->link_status.local_sap,
   1473                                 NFA_SNEP_ANY_SAP,
   1474                                 NFA_SNEP_FLAG_CLIENT);
   1475 
   1476     if (xx < NFA_SNEP_MAX_CONN)
   1477     {
   1478         evt_data.activated.client_handle = (NFA_HANDLE_GROUP_SNEP | xx);
   1479 
   1480         /* if LLCP link is activated */
   1481         if (p_data->link_status.is_activated == TRUE)
   1482         {
   1483             /* notify only client which may want to connect */
   1484             nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_ACTIVATED_EVT, &evt_data);
   1485         }
   1486         else
   1487         {
   1488             /* LLCP link is deactivated */
   1489             nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_DEACTIVATED_EVT, &evt_data);
   1490         }
   1491     }
   1492 }
   1493 
   1494 /*******************************************************************************
   1495 **
   1496 ** Function         nfa_snep_proc_llcp_tx_complete
   1497 **
   1498 ** Description      Processing LLCP tx complete event
   1499 **
   1500 **
   1501 ** Returns          none
   1502 **
   1503 *******************************************************************************/
   1504 void nfa_snep_proc_llcp_tx_complete (tLLCP_SAP_CBACK_DATA  *p_data)
   1505 {
   1506     UINT8              dlink;
   1507     tNFA_SNEP_EVT_DATA evt_data;
   1508 
   1509     SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_tx_complete ()");
   1510 
   1511     dlink = nfa_snep_sap_to_index (p_data->tx_complete.local_sap,
   1512                                    p_data->tx_complete.remote_sap,
   1513                                    NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CONNECTED);
   1514 
   1515     if (dlink < NFA_SNEP_MAX_CONN)
   1516     {
   1517         /* notify upper layer that transmission is complete */
   1518         evt_data.get_resp_cmpl.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
   1519         evt_data.get_resp_cmpl.p_buff      = nfa_snep_cb.conn[dlink].p_ndef_buff;
   1520 
   1521         nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_CMPL_EVT, &evt_data);
   1522         nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
   1523     }
   1524 }
   1525 
   1526 /*******************************************************************************
   1527 **
   1528 ** Function         nfa_snep_reg_server
   1529 **
   1530 ** Description      Allocate a connection control block as server and register to LLCP
   1531 **
   1532 **
   1533 ** Returns          TRUE to deallocate message
   1534 **
   1535 *******************************************************************************/
   1536 BOOLEAN nfa_snep_reg_server (tNFA_SNEP_MSG *p_msg)
   1537 {
   1538     tNFA_SNEP_EVT_DATA  evt_data;
   1539     UINT8               xx, local_sap = LLCP_INVALID_SAP;
   1540 
   1541     SNEP_TRACE_DEBUG0 ("nfa_snep_reg_server ()");
   1542 
   1543     xx = nfa_snep_allocate_cb ();
   1544 
   1545     if (xx < NFA_SNEP_MAX_CONN)
   1546     {
   1547         local_sap = LLCP_RegisterServer (p_msg->api_reg_server.server_sap,
   1548                                          LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
   1549                                          p_msg->api_reg_server.service_name,
   1550                                          nfa_snep_llcp_cback);
   1551     }
   1552 
   1553     BCM_STRNCPY_S (evt_data.reg.service_name, sizeof (evt_data.reg.service_name),
   1554                    p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
   1555     evt_data.reg.service_name[LLCP_MAX_SN_LEN] = 0x00;
   1556 
   1557     if ((xx == NFA_SNEP_MAX_CONN) || (local_sap == LLCP_INVALID_SAP))
   1558     {
   1559         SNEP_TRACE_ERROR0 ("Cannot allocate or register SNEP server");
   1560 
   1561         evt_data.reg.status = NFA_STATUS_FAILED;
   1562         p_msg->api_reg_server.p_cback (NFA_SNEP_REG_EVT, &evt_data);
   1563         return TRUE;
   1564     }
   1565 
   1566     if (!nfa_snep_cb.is_dta_mode)
   1567     {
   1568         /* if need to update WKS in LLCP Gen bytes */
   1569         if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
   1570         {
   1571             nfa_p2p_enable_listening (NFA_ID_SNEP, TRUE);
   1572             nfa_snep_cb.listen_enabled = TRUE;
   1573         }
   1574         else if (!nfa_snep_cb.listen_enabled)
   1575         {
   1576             nfa_p2p_enable_listening (NFA_ID_SNEP, FALSE);
   1577             nfa_snep_cb.listen_enabled = TRUE;
   1578         }
   1579     }
   1580 
   1581     nfa_snep_cb.conn[xx].local_sap  = local_sap;
   1582     nfa_snep_cb.conn[xx].remote_sap = LLCP_INVALID_SAP;
   1583     nfa_snep_cb.conn[xx].p_cback    = p_msg->api_reg_server.p_cback;
   1584     nfa_snep_cb.conn[xx].flags      = NFA_SNEP_FLAG_SERVER;
   1585 
   1586     evt_data.reg.status     = NFA_STATUS_OK;
   1587     evt_data.reg.reg_handle = (NFA_HANDLE_GROUP_SNEP | xx);
   1588 
   1589     /* notify NFA_SNEP_REG_EVT to application */
   1590     nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_REG_EVT, &evt_data);
   1591 
   1592     return TRUE;
   1593 }
   1594 
   1595 /*******************************************************************************
   1596 **
   1597 ** Function         nfa_snep_reg_client
   1598 **
   1599 ** Description      Allocate a connection control block as client and register to LLCP
   1600 **
   1601 **
   1602 ** Returns          TRUE to deallocate message
   1603 **
   1604 *******************************************************************************/
   1605 BOOLEAN nfa_snep_reg_client (tNFA_SNEP_MSG *p_msg)
   1606 {
   1607     tNFA_SNEP_EVT_DATA  evt_data;
   1608     UINT8               xx, local_sap = LLCP_INVALID_SAP;
   1609 
   1610     SNEP_TRACE_DEBUG0 ("nfa_snep_reg_client ()");
   1611 
   1612     xx = nfa_snep_allocate_cb ();
   1613 
   1614     if (xx < NFA_SNEP_MAX_CONN)
   1615     {
   1616         local_sap = LLCP_RegisterClient (LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
   1617                                          nfa_snep_llcp_cback);
   1618     }
   1619 
   1620     evt_data.reg.service_name[0] = 0x00;
   1621 
   1622     if ((xx == NFA_SNEP_MAX_CONN) || (local_sap == LLCP_INVALID_SAP))
   1623     {
   1624         SNEP_TRACE_ERROR0 ("Cannot allocate or register SNEP client");
   1625 
   1626         evt_data.reg.status = NFA_STATUS_FAILED;
   1627         p_msg->api_reg_client.p_cback (NFA_SNEP_REG_EVT, &evt_data);
   1628         return TRUE;
   1629     }
   1630 
   1631     nfa_snep_cb.conn[xx].local_sap  = local_sap;
   1632     nfa_snep_cb.conn[xx].remote_sap = LLCP_INVALID_SAP;
   1633     nfa_snep_cb.conn[xx].p_cback    = p_msg->api_reg_client.p_cback;
   1634     nfa_snep_cb.conn[xx].flags      = NFA_SNEP_FLAG_CLIENT;
   1635 
   1636     /* initialize timer callback */
   1637     nfa_snep_cb.conn[xx].timer.p_cback = nfa_snep_timer_cback;
   1638 
   1639     evt_data.reg.status     = NFA_STATUS_OK;
   1640     evt_data.reg.reg_handle = (NFA_HANDLE_GROUP_SNEP | xx);
   1641 
   1642     /* notify NFA_SNEP_REG_EVT to application */
   1643     nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_REG_EVT, &evt_data);
   1644 
   1645     return TRUE;
   1646 }
   1647 
   1648 /*******************************************************************************
   1649 **
   1650 ** Function         nfa_snep_dereg
   1651 **
   1652 ** Description      Deallocate a connection control block and deregister to LLCP
   1653 **                  LLCP will deallocate any data link connection created for this
   1654 **
   1655 ** Returns          TRUE to deallocate message
   1656 **
   1657 *******************************************************************************/
   1658 BOOLEAN nfa_snep_dereg (tNFA_SNEP_MSG *p_msg)
   1659 {
   1660     UINT8 xx;
   1661     UINT8 local_sap;
   1662 
   1663     SNEP_TRACE_DEBUG0 ("nfa_snep_dereg ()");
   1664 
   1665     xx = (UINT8) (p_msg->api_dereg.reg_handle & NFA_HANDLE_MASK);
   1666 
   1667     if (  (xx < NFA_SNEP_MAX_CONN)
   1668         &&(nfa_snep_cb.conn[xx].p_cback)
   1669         &&(nfa_snep_cb.conn[xx].flags & (NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CLIENT))  )
   1670     {
   1671         local_sap = nfa_snep_cb.conn[xx].local_sap;
   1672         LLCP_Deregister (local_sap);
   1673         nfa_snep_deallocate_cb (xx);
   1674     }
   1675     else
   1676     {
   1677         SNEP_TRACE_ERROR0 ("Cannot find SNEP server/client");
   1678         return TRUE;
   1679     }
   1680 
   1681     if (!nfa_snep_cb.is_dta_mode)
   1682     {
   1683         if (nfa_snep_cb.listen_enabled)
   1684         {
   1685             for (xx = 0; xx < NFA_SNEP_MAX_CONN; xx++)
   1686             {
   1687                 if (  (nfa_snep_cb.conn[xx].p_cback)
   1688                     &&(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_SERVER)  )
   1689                 {
   1690                     break;
   1691                 }
   1692             }
   1693 
   1694             if (xx >= NFA_SNEP_MAX_CONN)
   1695             {
   1696                 /* if need to update WKS in LLCP Gen bytes */
   1697                 if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
   1698                     nfa_p2p_disable_listening (NFA_ID_SNEP, TRUE);
   1699                 else
   1700                     nfa_p2p_disable_listening (NFA_ID_SNEP, FALSE);
   1701 
   1702                 nfa_snep_cb.listen_enabled = FALSE;
   1703             }
   1704             /* if need to update WKS in LLCP Gen bytes */
   1705             else if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
   1706             {
   1707                 nfa_p2p_enable_listening (NFA_ID_SNEP, TRUE);
   1708             }
   1709         }
   1710     }
   1711     return TRUE;
   1712 }
   1713 
   1714 /*******************************************************************************
   1715 **
   1716 ** Function         nfa_snep_connect
   1717 **
   1718 ** Description      Create data link connection for client
   1719 **
   1720 ** Returns          TRUE to deallocate message
   1721 **
   1722 *******************************************************************************/
   1723 BOOLEAN nfa_snep_connect (tNFA_SNEP_MSG *p_msg)
   1724 {
   1725     tLLCP_CONNECTION_PARAMS conn_params;
   1726     UINT8 xx;
   1727 
   1728     SNEP_TRACE_DEBUG0 ("nfa_snep_connect ()");
   1729 
   1730     xx = (UINT8) (p_msg->api_connect.client_handle & NFA_HANDLE_MASK);
   1731 
   1732     if (xx < NFA_SNEP_MAX_CONN)
   1733     {
   1734         nfa_snep_cb.conn[xx].congest = FALSE;
   1735 
   1736         /* Set remote_sap to SDP to find callback in case that link is deactivted before connected */
   1737         nfa_snep_cb.conn[xx].remote_sap = LLCP_SAP_SDP;
   1738 
   1739         /* in order to send NFA_SNEP_DISC_EVT in case of connection failure */
   1740         nfa_snep_cb.conn[xx].flags = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTING;
   1741 
   1742         /* create data link connection with server name */
   1743         conn_params.miu = NFA_SNEP_MIU;
   1744         conn_params.rw  = NFA_SNEP_RW;
   1745         BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn),
   1746                        p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
   1747         conn_params.sn[LLCP_MAX_SN_LEN] = 0;
   1748 
   1749         LLCP_ConnectReq (nfa_snep_cb.conn[xx].local_sap, LLCP_SAP_SDP, &conn_params);
   1750     }
   1751     return TRUE;
   1752 }
   1753 
   1754 /*******************************************************************************
   1755 **
   1756 ** Function         nfa_snep_get_req
   1757 **
   1758 ** Description      Send SNEP GET request on data link connection
   1759 **
   1760 ** Returns          TRUE to deallocate message
   1761 **
   1762 *******************************************************************************/
   1763 BOOLEAN nfa_snep_get_req (tNFA_SNEP_MSG *p_msg)
   1764 {
   1765     UINT8 dlink;
   1766 
   1767     SNEP_TRACE_DEBUG0 ("nfa_snep_get_req ()");
   1768 
   1769     dlink = (UINT8) (p_msg->api_get_req.conn_handle & NFA_HANDLE_MASK);
   1770 
   1771     if (  (dlink < NFA_SNEP_MAX_CONN)
   1772         &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
   1773     {
   1774         nfa_snep_cb.conn[dlink].tx_code           = NFA_SNEP_REQ_CODE_GET;
   1775         nfa_snep_cb.conn[dlink].buff_length       = p_msg->api_get_req.buff_length;
   1776         nfa_snep_cb.conn[dlink].ndef_length       = p_msg->api_get_req.ndef_length;
   1777         nfa_snep_cb.conn[dlink].p_ndef_buff       = p_msg->api_get_req.p_ndef_buff;
   1778         nfa_snep_cb.conn[dlink].acceptable_length = p_msg->api_get_req.buff_length;
   1779 
   1780         nfa_snep_send_msg (NFA_SNEP_REQ_CODE_GET, dlink);
   1781 
   1782         /* start timer for response from server */
   1783         nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
   1784     }
   1785     else
   1786     {
   1787         SNEP_TRACE_ERROR0 ("Data link connection is not established");
   1788     }
   1789     return TRUE;
   1790 }
   1791 
   1792 /*******************************************************************************
   1793 **
   1794 ** Function         nfa_snep_put_req
   1795 **
   1796 ** Description      Send SNEP PUT request on data link connection
   1797 **
   1798 ** Returns          TRUE to deallocate message
   1799 **
   1800 *******************************************************************************/
   1801 BOOLEAN nfa_snep_put_req (tNFA_SNEP_MSG *p_msg)
   1802 {
   1803     UINT8 dlink;
   1804 
   1805     SNEP_TRACE_DEBUG0 ("nfa_snep_put_req ()");
   1806 
   1807     dlink = (UINT8) (p_msg->api_put_req.conn_handle & NFA_HANDLE_MASK);
   1808 
   1809     if (  (dlink < NFA_SNEP_MAX_CONN)
   1810         &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
   1811     {
   1812         nfa_snep_cb.conn[dlink].tx_code     = NFA_SNEP_REQ_CODE_PUT;
   1813         nfa_snep_cb.conn[dlink].buff_length = p_msg->api_put_req.ndef_length;
   1814         nfa_snep_cb.conn[dlink].ndef_length = p_msg->api_put_req.ndef_length;
   1815         nfa_snep_cb.conn[dlink].p_ndef_buff = p_msg->api_put_req.p_ndef_buff;
   1816 
   1817         nfa_snep_send_msg (NFA_SNEP_REQ_CODE_PUT, dlink);
   1818 
   1819         /* start timer for response from server */
   1820         nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
   1821     }
   1822     else
   1823     {
   1824         SNEP_TRACE_ERROR0 ("Data link connection is not established");
   1825     }
   1826     return TRUE;
   1827 }
   1828 
   1829 /*******************************************************************************
   1830 **
   1831 ** Function         nfa_snep_get_resp
   1832 **
   1833 ** Description      Server responds to GET request
   1834 **
   1835 **
   1836 ** Returns          TRUE to deallocate message
   1837 **
   1838 *******************************************************************************/
   1839 BOOLEAN nfa_snep_get_resp (tNFA_SNEP_MSG *p_msg)
   1840 {
   1841     UINT8 dlink;
   1842 
   1843     SNEP_TRACE_DEBUG0 ("nfa_snep_get_resp ()");
   1844 
   1845     dlink = (UINT8) (p_msg->api_get_resp.conn_handle & NFA_HANDLE_MASK);
   1846 
   1847     if (  (dlink < NFA_SNEP_MAX_CONN)
   1848         &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
   1849     {
   1850         nfa_snep_cb.conn[dlink].buff_length = p_msg->api_get_resp.ndef_length;
   1851         nfa_snep_cb.conn[dlink].ndef_length = p_msg->api_get_resp.ndef_length;
   1852         nfa_snep_cb.conn[dlink].p_ndef_buff = p_msg->api_get_resp.p_ndef_buff;
   1853 
   1854         nfa_snep_cb.conn[dlink].tx_code     = p_msg->api_get_resp.resp_code;
   1855 
   1856         nfa_snep_send_msg (p_msg->api_get_resp.resp_code, dlink);
   1857     }
   1858     else
   1859     {
   1860         SNEP_TRACE_ERROR0 ("Data link connection is not established");
   1861     }
   1862     return TRUE;
   1863 }
   1864 
   1865 /*******************************************************************************
   1866 **
   1867 ** Function         nfa_snep_put_resp
   1868 **
   1869 ** Description      Server responds to PUT request
   1870 **
   1871 **
   1872 ** Returns          TRUE to deallocate message
   1873 **
   1874 *******************************************************************************/
   1875 BOOLEAN nfa_snep_put_resp (tNFA_SNEP_MSG *p_msg)
   1876 {
   1877     UINT8 dlink;
   1878 
   1879     SNEP_TRACE_DEBUG0 ("nfa_snep_put_resp ()");
   1880 
   1881     dlink = (UINT8) (p_msg->api_put_resp.conn_handle & NFA_HANDLE_MASK);
   1882 
   1883     if (  (dlink < NFA_SNEP_MAX_CONN)
   1884         &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
   1885     {
   1886         nfa_snep_cb.conn[dlink].tx_code = p_msg->api_put_resp.resp_code;
   1887 
   1888         nfa_snep_send_msg (p_msg->api_put_resp.resp_code, dlink);
   1889     }
   1890     else
   1891     {
   1892         SNEP_TRACE_ERROR0 ("Data link connection is not established");
   1893     }
   1894     return TRUE;
   1895 }
   1896 
   1897 /*******************************************************************************
   1898 **
   1899 ** Function         nfa_snep_disconnect
   1900 **
   1901 ** Description      Disconnect data link connection
   1902 **
   1903 **
   1904 ** Returns          TRUE to deallocate message
   1905 **
   1906 *******************************************************************************/
   1907 BOOLEAN nfa_snep_disconnect (tNFA_SNEP_MSG *p_msg)
   1908 {
   1909     UINT8 dlink;
   1910 
   1911     SNEP_TRACE_DEBUG0 ("nfa_snep_disconnect ()");
   1912 
   1913     dlink = (UINT8) (p_msg->api_disc.conn_handle & NFA_HANDLE_MASK);
   1914 
   1915     if (  (dlink < NFA_SNEP_MAX_CONN)
   1916         &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
   1917     {
   1918         LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
   1919                             nfa_snep_cb.conn[dlink].remote_sap,
   1920                             p_msg->api_disc.flush);
   1921     }
   1922     else
   1923     {
   1924         SNEP_TRACE_ERROR0 ("Data link connection is not established");
   1925     }
   1926     return TRUE;
   1927 }
   1928 
   1929 #if (BT_TRACE_VERBOSE == TRUE)
   1930 /*******************************************************************************
   1931 **
   1932 ** Function         nfa_snep_opcode
   1933 **
   1934 ** Description
   1935 **
   1936 ** Returns          string of event
   1937 **
   1938 *******************************************************************************/
   1939 static char *nfa_snep_opcode (UINT8 opcode)
   1940 {
   1941     switch (opcode)
   1942     {
   1943     case NFA_SNEP_REQ_CODE_CONTINUE:
   1944         return "REQ_CONTINUE";
   1945     case NFA_SNEP_REQ_CODE_GET:
   1946         return "REQ_GET";
   1947     case NFA_SNEP_REQ_CODE_PUT:
   1948         return "REQ_PUT";
   1949     case NFA_SNEP_REQ_CODE_REJECT:
   1950         return "REQ_REJECT";
   1951 
   1952     case NFA_SNEP_RESP_CODE_CONTINUE:
   1953         return "RESP_CONTINUE";
   1954     case NFA_SNEP_RESP_CODE_SUCCESS:
   1955         return "RESP_SUCCESS";
   1956     case NFA_SNEP_RESP_CODE_NOT_FOUND:
   1957         return "RESP_NOT_FOUND";
   1958     case NFA_SNEP_RESP_CODE_EXCESS_DATA:
   1959         return "RESP_EXCESS_DATA";
   1960     case NFA_SNEP_RESP_CODE_BAD_REQ:
   1961         return "RESP_BAD_REQ";
   1962     case NFA_SNEP_RESP_CODE_NOT_IMPLM:
   1963         return "RESP_NOT_IMPLM";
   1964     case NFA_SNEP_RESP_CODE_UNSUPP_VER:
   1965         return "RESP_UNSUPP_VER";
   1966     case NFA_SNEP_RESP_CODE_REJECT:
   1967         return "RESP_REJECT";
   1968 
   1969     default:
   1970         return "Reserved opcode";
   1971     }
   1972 }
   1973 
   1974 #endif  /* Debug Functions */
   1975 
   1976