Home | History | Annotate | Download | only in pan
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 1999-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 file contains main functions to support PAN profile
     22  *  commands and events.
     23  *
     24  *****************************************************************************/
     25 
     26 #include <string.h>
     27 #include <stdio.h>
     28 #include "bt_common.h"
     29 #include "bnep_api.h"
     30 #include "pan_api.h"
     31 #include "pan_int.h"
     32 #include "sdp_api.h"
     33 #include "sdpdefs.h"
     34 #include "l2c_api.h"
     35 #include "hcidefs.h"
     36 #include "btm_api.h"
     37 
     38 
     39 static const UINT8 pan_proto_elem_data[]   = {
     40                                    0x35, 0x18,          /* data element sequence of length 0x18 bytes */
     41                                    0x35, 0x06,          /* data element sequence for L2CAP descriptor */
     42                                    0x19, 0x01, 0x00,    /* UUID for L2CAP - 0x0100 */
     43                                    0x09, 0x00, 0x0F,    /* PSM for BNEP - 0x000F */
     44                                    0x35, 0x0E,          /* data element seqence for BNEP descriptor */
     45                                    0x19, 0x00, 0x0F,    /* UUID for BNEP - 0x000F */
     46                                    0x09, 0x01, 0x00,    /* BNEP specific parameter 0 -- Version of BNEP = version 1 = 0x0001 */
     47                                    0x35, 0x06,          /* BNEP specific parameter 1 -- Supported network packet type list */
     48                                    0x09, 0x08, 0x00,    /* network packet type IPv4 = 0x0800 */
     49                                    0x09, 0x08, 0x06     /* network packet type ARP  = 0x0806 */
     50 };
     51 
     52 /*******************************************************************************
     53 **
     54 ** Function         pan_register_with_sdp
     55 **
     56 ** Description
     57 **
     58 ** Returns
     59 **
     60 *******************************************************************************/
     61 UINT32 pan_register_with_sdp (UINT16 uuid, UINT8 sec_mask, char *p_name, char *p_desc)
     62 {
     63     UINT32  sdp_handle;
     64     UINT16  browse_list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
     65     UINT16  security = 0;
     66     UINT32  proto_len = (UINT32)pan_proto_elem_data[1];
     67 
     68     /* Create a record */
     69     sdp_handle = SDP_CreateRecord ();
     70 
     71     if (sdp_handle == 0)
     72     {
     73         PAN_TRACE_ERROR ("PAN_SetRole - could not create SDP record");
     74         return 0;
     75     }
     76 
     77     /* Service Class ID List */
     78     SDP_AddServiceClassIdList (sdp_handle, 1, &uuid);
     79 
     80     /* Add protocol element sequence from the constant string */
     81     SDP_AddAttribute (sdp_handle, ATTR_ID_PROTOCOL_DESC_LIST, DATA_ELE_SEQ_DESC_TYPE,
     82                       proto_len, (UINT8 *)(pan_proto_elem_data+2));
     83 
     84 #if 0
     85     availability = 0xFF;
     86     SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_AVAILABILITY, UINT_DESC_TYPE, 1, &availability);
     87 #endif
     88 
     89     /* Language base */
     90     SDP_AddLanguageBaseAttrIDList (sdp_handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID);
     91 
     92     /* Profile descriptor list */
     93     SDP_AddProfileDescriptorList (sdp_handle, uuid, PAN_PROFILE_VERSION);
     94 
     95     /* Service Name */
     96     SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
     97                         (UINT8) (strlen(p_name) + 1), (UINT8 *)p_name);
     98 
     99     /* Service description */
    100     SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE,
    101                         (UINT8) (strlen(p_desc) + 1), (UINT8 *)p_desc);
    102 
    103     /* Security description */
    104     if (sec_mask)
    105     {
    106         UINT16_TO_BE_FIELD(&security, 0x0001);
    107     }
    108     SDP_AddAttribute (sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2, (UINT8 *)&security);
    109 
    110 #if (defined (PAN_SUPPORTS_ROLE_NAP) && PAN_SUPPORTS_ROLE_NAP == TRUE)
    111     if (uuid == UUID_SERVCLASS_NAP)
    112     {
    113         UINT16  NetAccessType = 0x0005;      /* Ethernet */
    114         UINT32  NetAccessRate = 0x0001312D0; /* 10Mb/sec */
    115         UINT8   array[10], *p;
    116 
    117         /* Net access type. */
    118         p = array;
    119         UINT16_TO_BE_STREAM (p, NetAccessType);
    120         SDP_AddAttribute (sdp_handle, ATTR_ID_NET_ACCESS_TYPE, UINT_DESC_TYPE, 2, array);
    121 
    122         /* Net access rate. */
    123         p = array;
    124         UINT32_TO_BE_STREAM (p, NetAccessRate);
    125         SDP_AddAttribute (sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4, array);
    126 
    127         /* Register with Security Manager for the specific security level */
    128         if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_NAP,
    129                                     sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP))
    130          || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_NAP,
    131                                     sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP)))
    132         {
    133             PAN_TRACE_ERROR ("PAN Security Registration failed for PANU");
    134         }
    135     }
    136 #endif
    137 #if (defined (PAN_SUPPORTS_ROLE_GN) && PAN_SUPPORTS_ROLE_GN == TRUE)
    138     if (uuid == UUID_SERVCLASS_GN)
    139     {
    140         if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_GN,
    141                                     sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN))
    142          || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_GN,
    143                                     sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN)))
    144         {
    145             PAN_TRACE_ERROR ("PAN Security Registration failed for GN");
    146         }
    147     }
    148 #endif
    149 #if (defined (PAN_SUPPORTS_ROLE_PANU) && PAN_SUPPORTS_ROLE_PANU == TRUE)
    150     if (uuid == UUID_SERVCLASS_PANU)
    151     {
    152         if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
    153                                     sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU))
    154          || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
    155                                     sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU)))
    156         {
    157             PAN_TRACE_ERROR ("PAN Security Registration failed for PANU");
    158         }
    159     }
    160 #endif
    161 
    162     /* Make the service browsable */
    163     SDP_AddUuidSequence (sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list);
    164 
    165 
    166     return sdp_handle;
    167 }
    168 
    169 
    170 
    171 /*******************************************************************************
    172 **
    173 ** Function         pan_allocate_pcb
    174 **
    175 ** Description
    176 **
    177 ** Returns
    178 **
    179 *******************************************************************************/
    180 tPAN_CONN *pan_allocate_pcb (BD_ADDR p_bda, UINT16 handle)
    181 {
    182     UINT16      i;
    183 
    184     for (i=0; i<MAX_PAN_CONNS; i++)
    185     {
    186         if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE &&
    187             pan_cb.pcb[i].handle == handle)
    188             return NULL;
    189     }
    190 
    191     for (i=0; i<MAX_PAN_CONNS; i++)
    192     {
    193         if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE &&
    194             memcmp (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0)
    195             return NULL;
    196     }
    197 
    198     for (i=0; i<MAX_PAN_CONNS; i++)
    199     {
    200         if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE)
    201         {
    202             memset (&(pan_cb.pcb[i]), 0, sizeof (tPAN_CONN));
    203             memcpy (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN);
    204             pan_cb.pcb[i].handle = handle;
    205             return &(pan_cb.pcb[i]);
    206         }
    207     }
    208     return NULL;
    209 }
    210 
    211 
    212 /*******************************************************************************
    213 **
    214 ** Function         pan_get_pcb_by_handle
    215 **
    216 ** Description
    217 **
    218 ** Returns
    219 **
    220 *******************************************************************************/
    221 tPAN_CONN *pan_get_pcb_by_handle (UINT16 handle)
    222 {
    223     UINT16      i;
    224 
    225     for (i=0; i<MAX_PAN_CONNS; i++)
    226     {
    227         if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE &&
    228             pan_cb.pcb[i].handle == handle)
    229             return &(pan_cb.pcb[i]);
    230     }
    231 
    232     return NULL;
    233 }
    234 
    235 
    236 /*******************************************************************************
    237 **
    238 ** Function         pan_get_pcb_by_addr
    239 **
    240 ** Description
    241 **
    242 ** Returns
    243 **
    244 *******************************************************************************/
    245 tPAN_CONN *pan_get_pcb_by_addr (BD_ADDR p_bda)
    246 {
    247     UINT16      i;
    248 
    249     for (i=0; i<MAX_PAN_CONNS; i++)
    250     {
    251         if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE)
    252             continue;
    253 
    254         if (memcmp (pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0)
    255             return &(pan_cb.pcb[i]);
    256 
    257         /*
    258         if (pan_cb.pcb[i].mfilter_present &&
    259             (memcmp (p_bda, pan_cb.pcb[i].multi_cast_bridge, BD_ADDR_LEN) == 0))
    260             return &(pan_cb.pcb[i]);
    261         */
    262     }
    263 
    264     return NULL;
    265 }
    266 
    267 
    268 
    269 
    270 /*******************************************************************************
    271 **
    272 ** Function         pan_close_all_connections
    273 **
    274 ** Description
    275 **
    276 ** Returns          void
    277 **
    278 *******************************************************************************/
    279 void pan_close_all_connections (void)
    280 {
    281     UINT16      i;
    282 
    283     for (i=0; i<MAX_PAN_CONNS; i++)
    284     {
    285         if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE)
    286         {
    287             BNEP_Disconnect (pan_cb.pcb[i].handle);
    288             pan_cb.pcb[i].con_state = PAN_STATE_IDLE;
    289         }
    290     }
    291 
    292     pan_cb.active_role = PAN_ROLE_INACTIVE;
    293     pan_cb.num_conns   = 0;
    294     return;
    295 }
    296 
    297 
    298 /*******************************************************************************
    299 **
    300 ** Function         pan_release_pcb
    301 **
    302 ** Description      This function releases a PCB.
    303 **
    304 ** Returns          void
    305 **
    306 *******************************************************************************/
    307 void pan_release_pcb (tPAN_CONN *p_pcb)
    308 {
    309     /* Drop any response pointer we may be holding */
    310     memset (p_pcb, 0, sizeof (tPAN_CONN));
    311     p_pcb->con_state = PAN_STATE_IDLE;
    312 }
    313 
    314 
    315 /*******************************************************************************
    316 **
    317 ** Function         pan_dump_status
    318 **
    319 ** Description      This function dumps the pan control block and connection
    320 **                  blocks information
    321 **
    322 ** Returns          none
    323 **
    324 *******************************************************************************/
    325 void pan_dump_status (void)
    326 {
    327 #if (defined (PAN_SUPPORTS_DEBUG_DUMP) && PAN_SUPPORTS_DEBUG_DUMP == TRUE)
    328     UINT16          i;
    329     char            buff[200];
    330     tPAN_CONN      *p_pcb;
    331 
    332     PAN_TRACE_DEBUG ("PAN role %x, active role %d, num_conns %d",
    333         pan_cb.role, pan_cb.active_role, pan_cb.num_conns);
    334 
    335     for (i = 0, p_pcb = pan_cb.pcb; i < MAX_PAN_CONNS; i++, p_pcb++)
    336     {
    337         sprintf (buff, "%d state %d, handle %d, src 0x%x, dst 0x%x, BD %x.%x.%x.%x.%x.%x",
    338             i, p_pcb->con_state, p_pcb->handle, p_pcb->src_uuid, p_pcb->dst_uuid,
    339             p_pcb->rem_bda[0], p_pcb->rem_bda[1], p_pcb->rem_bda[2],
    340             p_pcb->rem_bda[3], p_pcb->rem_bda[4], p_pcb->rem_bda[5]);
    341 
    342         PAN_TRACE_DEBUG (buff);
    343     }
    344 #endif
    345 }
    346 
    347 
    348 
    349