| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 "gki.h" | 
 | 28 | #include "bt_types.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" | 
| Mike J. Chen | e5febfe | 2014-01-31 15:04:41 -0800 | [diff] [blame] | 37 | #include "bta_sys.h" | 
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 38 |  | 
 | 39 |  | 
 | 40 | /******************************************************************************* | 
 | 41 | ** | 
 | 42 | ** Function         PAN_Register | 
 | 43 | ** | 
 | 44 | ** Description      This function is called by the application to register | 
 | 45 | **                  its callbacks with PAN profile. The application then | 
 | 46 | **                  should set the PAN role explicitly. | 
 | 47 | ** | 
 | 48 | ** Parameters:      p_register - contains all callback function pointers | 
 | 49 | ** | 
 | 50 | ** | 
 | 51 | ** Returns          none | 
 | 52 | ** | 
 | 53 | *******************************************************************************/ | 
 | 54 | void PAN_Register (tPAN_REGISTER *p_register) | 
 | 55 | { | 
 | 56 |     BTM_SetDiscoverability (BTM_GENERAL_DISCOVERABLE, 0, 0); | 
 | 57 |     BTM_SetConnectability (BTM_CONNECTABLE, 0, 0); | 
 | 58 |  | 
 | 59 |     pan_register_with_bnep (); | 
 | 60 |  | 
 | 61 |     if (!p_register) | 
 | 62 |         return; | 
 | 63 |  | 
 | 64 |     pan_cb.pan_conn_state_cb    = p_register->pan_conn_state_cb; | 
 | 65 |     pan_cb.pan_bridge_req_cb    = p_register->pan_bridge_req_cb; | 
 | 66 |     pan_cb.pan_data_buf_ind_cb  = p_register->pan_data_buf_ind_cb; | 
 | 67 |     pan_cb.pan_data_ind_cb      = p_register->pan_data_ind_cb; | 
 | 68 |     pan_cb.pan_pfilt_ind_cb     = p_register->pan_pfilt_ind_cb; | 
 | 69 |     pan_cb.pan_mfilt_ind_cb     = p_register->pan_mfilt_ind_cb; | 
 | 70 |     pan_cb.pan_tx_data_flow_cb  = p_register->pan_tx_data_flow_cb; | 
 | 71 |  | 
 | 72 |     return; | 
 | 73 | } | 
 | 74 |  | 
 | 75 |  | 
 | 76 |  | 
 | 77 | /******************************************************************************* | 
 | 78 | ** | 
 | 79 | ** Function         PAN_Deregister | 
 | 80 | ** | 
 | 81 | ** Description      This function is called by the application to de-register | 
 | 82 | **                  its callbacks with PAN profile. This will make the PAN to | 
 | 83 | **                  become inactive. This will deregister PAN services from SDP | 
 | 84 | **                  and close all active connections | 
 | 85 | ** | 
 | 86 | ** Parameters:      none | 
 | 87 | ** | 
 | 88 | ** | 
 | 89 | ** Returns          none | 
 | 90 | ** | 
 | 91 | *******************************************************************************/ | 
 | 92 | void PAN_Deregister (void) | 
 | 93 | { | 
 | 94 |     pan_cb.pan_bridge_req_cb    = NULL; | 
 | 95 |     pan_cb.pan_data_buf_ind_cb  = NULL; | 
 | 96 |     pan_cb.pan_data_ind_cb      = NULL; | 
 | 97 |     pan_cb.pan_conn_state_cb    = NULL; | 
 | 98 |     pan_cb.pan_pfilt_ind_cb     = NULL; | 
 | 99 |     pan_cb.pan_mfilt_ind_cb     = NULL; | 
 | 100 |  | 
 | 101 |     PAN_SetRole (PAN_ROLE_INACTIVE, NULL, NULL, NULL, NULL); | 
 | 102 |     BNEP_Deregister (); | 
 | 103 |  | 
 | 104 |     return; | 
 | 105 | } | 
 | 106 |  | 
 | 107 |  | 
 | 108 |  | 
 | 109 |  | 
 | 110 | /******************************************************************************* | 
 | 111 | ** | 
 | 112 | ** Function         PAN_SetRole | 
 | 113 | ** | 
 | 114 | ** Description      This function is called by the application to set the PAN | 
 | 115 | **                  profile role. This should be called after PAN_Register. | 
 | 116 | **                  This can be called any time to change the PAN role | 
 | 117 | ** | 
 | 118 | ** Parameters:      role        - is bit map of roles to be active | 
 | 119 | **                                      PAN_ROLE_CLIENT is for PANU role | 
 | 120 | **                                      PAN_ROLE_GN_SERVER is for GN role | 
 | 121 | **                                      PAN_ROLE_NAP_SERVER is for NAP role | 
 | 122 | **                  sec_mask    - Security mask for different roles | 
 | 123 | **                                      It is array of UINT8. The byte represent the | 
 | 124 | **                                      security for roles PANU, GN and NAP in order | 
 | 125 | **                  p_user_name - Service name for PANU role | 
 | 126 | **                  p_gn_name   - Service name for GN role | 
 | 127 | **                  p_nap_name  - Service name for NAP role | 
 | 128 | **                                      Can be NULL if user wants it to be default | 
 | 129 | ** | 
 | 130 | ** Returns          PAN_SUCCESS     - if the role is set successfully | 
 | 131 | **                  PAN_FAILURE     - if the role is not valid | 
 | 132 | ** | 
 | 133 | *******************************************************************************/ | 
 | 134 | tPAN_RESULT PAN_SetRole (UINT8 role, | 
 | 135 |                          UINT8 *sec_mask, | 
 | 136 |                          char *p_user_name, | 
 | 137 |                          char *p_gn_name, | 
 | 138 |                          char *p_nap_name) | 
 | 139 | { | 
 | 140 |     char                *p_desc; | 
 | 141 |     UINT8               security[3] = {PAN_PANU_SECURITY_LEVEL, | 
 | 142 |                                        PAN_GN_SECURITY_LEVEL, | 
 | 143 |                                        PAN_NAP_SECURITY_LEVEL}; | 
 | 144 |     UINT8               *p_sec; | 
 | 145 |  | 
 | 146 |     /* If the role is not a valid combination reject it */ | 
 | 147 |     if ((!(role & (PAN_ROLE_CLIENT | PAN_ROLE_GN_SERVER | PAN_ROLE_NAP_SERVER))) && | 
 | 148 |         role != PAN_ROLE_INACTIVE) | 
 | 149 |     { | 
 | 150 |         PAN_TRACE_ERROR1 ("PAN role %d is invalid", role); | 
 | 151 |         return PAN_FAILURE; | 
 | 152 |     } | 
 | 153 |  | 
 | 154 |     /* If the current active role is same as the role being set do nothing */ | 
 | 155 |     if (pan_cb.role == role) | 
 | 156 |     { | 
 | 157 |         PAN_TRACE_EVENT1 ("PAN role already was set to: %d", role); | 
 | 158 |         return PAN_SUCCESS; | 
 | 159 |     } | 
 | 160 |  | 
 | 161 |     if (!sec_mask) | 
 | 162 |         p_sec = security; | 
 | 163 |     else | 
 | 164 |         p_sec = sec_mask; | 
 | 165 |  | 
 | 166 |     /* Register all the roles with SDP */ | 
 | 167 |     PAN_TRACE_API1 ("PAN_SetRole() called with role 0x%x", role); | 
 | 168 | #if (defined (PAN_SUPPORTS_ROLE_NAP) && PAN_SUPPORTS_ROLE_NAP == TRUE) | 
 | 169 |     /* Check the service name */ | 
 | 170 |     if ((p_nap_name == NULL) || (*p_nap_name == 0)) | 
 | 171 |         p_nap_name = PAN_NAP_DEFAULT_SERVICE_NAME; | 
 | 172 |  | 
 | 173 |     if (role & PAN_ROLE_NAP_SERVER) | 
 | 174 |     { | 
 | 175 |         /* Registering for NAP service with SDP */ | 
 | 176 |         p_desc = PAN_NAP_DEFAULT_DESCRIPTION; | 
 | 177 |  | 
 | 178 |         if (pan_cb.pan_nap_sdp_handle != 0) | 
 | 179 |             SDP_DeleteRecord (pan_cb.pan_nap_sdp_handle); | 
 | 180 |  | 
 | 181 |         pan_cb.pan_nap_sdp_handle = pan_register_with_sdp (UUID_SERVCLASS_NAP, p_sec[2], p_nap_name, p_desc); | 
 | 182 | // btla-specific ++ | 
 | 183 |         bta_sys_add_uuid(UUID_SERVCLASS_NAP); | 
 | 184 | // btla-specific -- | 
 | 185 |     } | 
 | 186 |     /* If the NAP role is already active and now being cleared delete the record */ | 
 | 187 |     else if (pan_cb.role & PAN_ROLE_NAP_SERVER) | 
 | 188 |     { | 
 | 189 |         if (pan_cb.pan_nap_sdp_handle != 0) | 
 | 190 |         { | 
 | 191 |             SDP_DeleteRecord (pan_cb.pan_nap_sdp_handle); | 
 | 192 |             pan_cb.pan_nap_sdp_handle = 0; | 
 | 193 | // btla-specific ++ | 
 | 194 |             bta_sys_remove_uuid(UUID_SERVCLASS_NAP); | 
 | 195 | // btla-specific -- | 
 | 196 |         } | 
 | 197 |     } | 
 | 198 | #endif | 
 | 199 |  | 
 | 200 | #if (defined (PAN_SUPPORTS_ROLE_GN) && PAN_SUPPORTS_ROLE_GN == TRUE) | 
 | 201 |     /* Check the service name */ | 
 | 202 |     if ((p_gn_name == NULL) || (*p_gn_name == 0)) | 
 | 203 |         p_gn_name = PAN_GN_DEFAULT_SERVICE_NAME; | 
 | 204 |  | 
 | 205 |     if (role & PAN_ROLE_GN_SERVER) | 
 | 206 |     { | 
 | 207 |         /* Registering for GN service with SDP */ | 
 | 208 |         p_desc = PAN_GN_DEFAULT_DESCRIPTION; | 
 | 209 |  | 
 | 210 |         if (pan_cb.pan_gn_sdp_handle != 0) | 
 | 211 |             SDP_DeleteRecord (pan_cb.pan_gn_sdp_handle); | 
 | 212 |  | 
 | 213 |         pan_cb.pan_gn_sdp_handle = pan_register_with_sdp (UUID_SERVCLASS_GN, p_sec[1], p_gn_name, p_desc); | 
 | 214 | // btla-specific ++ | 
 | 215 |         bta_sys_add_uuid(UUID_SERVCLASS_GN); | 
 | 216 | // btla-specific -- | 
 | 217 |     } | 
 | 218 |     /* If the GN role is already active and now being cleared delete the record */ | 
 | 219 |     else if (pan_cb.role & PAN_ROLE_GN_SERVER) | 
 | 220 |     { | 
 | 221 |         if (pan_cb.pan_gn_sdp_handle != 0) | 
 | 222 |         { | 
 | 223 |             SDP_DeleteRecord (pan_cb.pan_gn_sdp_handle); | 
 | 224 |             pan_cb.pan_gn_sdp_handle = 0; | 
 | 225 | // btla-specific ++ | 
 | 226 |             bta_sys_remove_uuid(UUID_SERVCLASS_GN); | 
 | 227 | // btla-specific -- | 
 | 228 |         } | 
 | 229 |     } | 
 | 230 | #endif | 
 | 231 |  | 
 | 232 | #if (defined (PAN_SUPPORTS_ROLE_PANU) && PAN_SUPPORTS_ROLE_PANU == TRUE) | 
 | 233 |     /* Check the service name */ | 
 | 234 |     if ((p_user_name == NULL) || (*p_user_name == 0)) | 
 | 235 |         p_user_name = PAN_PANU_DEFAULT_SERVICE_NAME; | 
 | 236 |  | 
 | 237 |     if (role & PAN_ROLE_CLIENT) | 
 | 238 |     { | 
 | 239 |         /* Registering for PANU service with SDP */ | 
 | 240 |         p_desc = PAN_PANU_DEFAULT_DESCRIPTION; | 
 | 241 |         if (pan_cb.pan_user_sdp_handle != 0) | 
 | 242 |             SDP_DeleteRecord (pan_cb.pan_user_sdp_handle); | 
 | 243 |  | 
 | 244 |         pan_cb.pan_user_sdp_handle = pan_register_with_sdp (UUID_SERVCLASS_PANU, p_sec[0], p_user_name, p_desc); | 
 | 245 | // btla-specific ++ | 
 | 246 |         bta_sys_add_uuid(UUID_SERVCLASS_PANU); | 
 | 247 | // btla-specific -- | 
 | 248 |     } | 
 | 249 |     /* If the PANU role is already active and now being cleared delete the record */ | 
 | 250 |     else if (pan_cb.role & PAN_ROLE_CLIENT) | 
 | 251 |     { | 
 | 252 |         if (pan_cb.pan_user_sdp_handle != 0) | 
 | 253 |         { | 
 | 254 |             SDP_DeleteRecord (pan_cb.pan_user_sdp_handle); | 
 | 255 |             pan_cb.pan_user_sdp_handle = 0; | 
 | 256 | // btla-specific ++ | 
 | 257 |             bta_sys_remove_uuid(UUID_SERVCLASS_PANU); | 
 | 258 | // btla-specific -- | 
 | 259 |         } | 
 | 260 |     } | 
 | 261 | #endif | 
 | 262 |  | 
 | 263 |     /* Check if it is a shutdown request */ | 
 | 264 |     if (role == PAN_ROLE_INACTIVE) | 
 | 265 |         pan_close_all_connections (); | 
 | 266 |  | 
 | 267 |     pan_cb.role = role; | 
 | 268 |     PAN_TRACE_EVENT1 ("PAN role set to: %d", role); | 
 | 269 |     return PAN_SUCCESS; | 
 | 270 | } | 
 | 271 |  | 
 | 272 |  | 
 | 273 |  | 
 | 274 | /******************************************************************************* | 
 | 275 | ** | 
 | 276 | ** Function         PAN_Connect | 
 | 277 | ** | 
 | 278 | ** Description      This function is called by the application to initiate a | 
 | 279 | **                  connection to the remote device | 
 | 280 | ** | 
 | 281 | ** Parameters:      rem_bda     - BD Addr of the remote device | 
 | 282 | **                  src_role    - Role of the local device for the connection | 
 | 283 | **                  dst_role    - Role of the remote device for the connection | 
 | 284 | **                                      PAN_ROLE_CLIENT is for PANU role | 
 | 285 | **                                      PAN_ROLE_GN_SERVER is for GN role | 
 | 286 | **                                      PAN_ROLE_NAP_SERVER is for NAP role | 
 | 287 | **                  *handle     - Pointer for returning Handle to the connection | 
 | 288 | ** | 
 | 289 | ** Returns          PAN_SUCCESS      - if the connection is initiated successfully | 
 | 290 | **                  PAN_NO_RESOURCES - resources are not sufficent | 
 | 291 | **                  PAN_FAILURE      - if the connection cannot be initiated | 
 | 292 | **                                           this can be because of the combination of | 
 | 293 | **                                           src and dst roles may not be valid or | 
 | 294 | **                                           allowed at that point of time | 
 | 295 | ** | 
 | 296 | *******************************************************************************/ | 
 | 297 | tPAN_RESULT PAN_Connect (BD_ADDR rem_bda, UINT8 src_role, UINT8 dst_role, UINT16 *handle) | 
 | 298 | { | 
 | 299 |     tPAN_CONN       *pcb; | 
 | 300 |     tBNEP_RESULT    result; | 
 | 301 |     tBT_UUID        src_uuid, dst_uuid; | 
 | 302 |     UINT8           service_id; | 
 | 303 |     UINT32 mx_chan_id; | 
 | 304 |  | 
 | 305 |     /* | 
 | 306 |     ** Initialize the handle so that in case of failure return values | 
 | 307 |     ** the profile will not get confused | 
 | 308 |     */ | 
 | 309 |     *handle = BNEP_INVALID_HANDLE; | 
 | 310 |  | 
 | 311 |     /* Check if PAN is active or not */ | 
 | 312 |     if (!(pan_cb.role & src_role)) | 
 | 313 |     { | 
 | 314 |         PAN_TRACE_ERROR1 ("PAN is not active for the role %d", src_role); | 
 | 315 |         return PAN_FAILURE; | 
 | 316 |     } | 
 | 317 |  | 
 | 318 |     /* Validate the parameters before proceeding */ | 
 | 319 |     if ((src_role != PAN_ROLE_CLIENT && src_role != PAN_ROLE_GN_SERVER && src_role != PAN_ROLE_NAP_SERVER) || | 
 | 320 |         (dst_role != PAN_ROLE_CLIENT && dst_role != PAN_ROLE_GN_SERVER && dst_role != PAN_ROLE_NAP_SERVER)) | 
 | 321 |     { | 
 | 322 |         PAN_TRACE_ERROR2 ("Either source %d or destination role %d is invalid", src_role, dst_role); | 
 | 323 |         return PAN_FAILURE; | 
 | 324 |     } | 
 | 325 |  | 
 | 326 |     /* Check if connection exists for this remote device */ | 
 | 327 |     pcb = pan_get_pcb_by_addr (rem_bda); | 
 | 328 |  | 
 | 329 |     /* If we are PANU for this role validate destination role */ | 
 | 330 |     if (src_role == PAN_ROLE_CLIENT) | 
 | 331 |     { | 
 | 332 |         if ((pan_cb.num_conns > 1) || (pan_cb.num_conns && (!pcb))) | 
 | 333 |         { | 
 | 334 |             /* | 
 | 335 |             ** If the request is not for existing connection reject it | 
 | 336 |             ** because if there is already a connection we cannot accept | 
 | 337 |             ** another connection in PANU role | 
 | 338 |             */ | 
 | 339 |             PAN_TRACE_ERROR0 ("Cannot make PANU connections when there are more than one connection"); | 
 | 340 |             return PAN_INVALID_SRC_ROLE; | 
 | 341 |         } | 
 | 342 |  | 
 | 343 |         src_uuid.uu.uuid16 = UUID_SERVCLASS_PANU; | 
 | 344 |         if (dst_role == PAN_ROLE_CLIENT) | 
 | 345 |         { | 
 | 346 |             service_id = BTM_SEC_SERVICE_BNEP_PANU; | 
 | 347 |             dst_uuid.uu.uuid16 = UUID_SERVCLASS_PANU; | 
 | 348 |         } | 
 | 349 |         else if (dst_role == PAN_ROLE_GN_SERVER) | 
 | 350 |         { | 
 | 351 |             service_id = BTM_SEC_SERVICE_BNEP_GN; | 
 | 352 |             dst_uuid.uu.uuid16 = UUID_SERVCLASS_GN; | 
 | 353 |         } | 
 | 354 |         else | 
 | 355 |         { | 
 | 356 |             service_id = BTM_SEC_SERVICE_BNEP_NAP; | 
 | 357 |             dst_uuid.uu.uuid16 = UUID_SERVCLASS_NAP; | 
 | 358 |         } | 
 | 359 |         mx_chan_id = dst_uuid.uu.uuid16; | 
 | 360 |     } | 
 | 361 |     /* If destination is PANU role validate source role */ | 
 | 362 |     else if (dst_role == PAN_ROLE_CLIENT) | 
 | 363 |     { | 
 | 364 |         if (pan_cb.num_conns && pan_cb.active_role == PAN_ROLE_CLIENT && !pcb) | 
 | 365 |         { | 
 | 366 |             PAN_TRACE_ERROR0 ("Device already have a connection in PANU role"); | 
 | 367 |             return PAN_INVALID_SRC_ROLE; | 
 | 368 |         } | 
 | 369 |  | 
 | 370 |         dst_uuid.uu.uuid16 = UUID_SERVCLASS_PANU; | 
 | 371 |         if (src_role == PAN_ROLE_GN_SERVER) | 
 | 372 |         { | 
 | 373 |             service_id = BTM_SEC_SERVICE_BNEP_GN; | 
 | 374 |             src_uuid.uu.uuid16 = UUID_SERVCLASS_GN; | 
 | 375 |         } | 
 | 376 |         else | 
 | 377 |         { | 
 | 378 |             service_id = BTM_SEC_SERVICE_BNEP_NAP; | 
 | 379 |             src_uuid.uu.uuid16 = UUID_SERVCLASS_NAP; | 
 | 380 |         } | 
 | 381 |         mx_chan_id = src_uuid.uu.uuid16; | 
 | 382 |     } | 
 | 383 |     /* The role combination is not valid */ | 
 | 384 |     else | 
 | 385 |     { | 
 | 386 |         PAN_TRACE_ERROR2 ("Source %d and Destination roles %d are not valid combination", | 
 | 387 |             src_role, dst_role); | 
 | 388 |         return PAN_FAILURE; | 
 | 389 |     } | 
 | 390 |  | 
 | 391 |     /* Allocate control block and initiate connection */ | 
 | 392 |     if (!pcb) | 
 | 393 |         pcb = pan_allocate_pcb (rem_bda, BNEP_INVALID_HANDLE); | 
 | 394 |     if (!pcb) | 
 | 395 |     { | 
 | 396 |         PAN_TRACE_ERROR0 ("PAN Connection failed because of no resources"); | 
 | 397 |         return PAN_NO_RESOURCES; | 
 | 398 |     } | 
 | 399 |     BTM_SetOutService(rem_bda, BTM_SEC_SERVICE_BNEP_PANU, mx_chan_id); | 
 | 400 |  | 
 | 401 |     PAN_TRACE_API6 ("PAN_Connect() for BD Addr %x.%x.%x.%x.%x.%x", | 
 | 402 |         rem_bda[0], rem_bda[1], rem_bda[2], rem_bda[3], rem_bda[4], rem_bda[5]); | 
 | 403 |     if (pcb->con_state == PAN_STATE_IDLE) | 
 | 404 |     { | 
 | 405 |         pan_cb.num_conns++; | 
 | 406 |     } | 
 | 407 |     else if (pcb->con_state == PAN_STATE_CONNECTED) | 
 | 408 |     { | 
 | 409 |         pcb->con_flags |= PAN_FLAGS_CONN_COMPLETED; | 
 | 410 |     } | 
 | 411 |     else | 
 | 412 |         /* PAN connection is still in progress */ | 
 | 413 |         return PAN_WRONG_STATE; | 
 | 414 |  | 
 | 415 |     pcb->con_state = PAN_STATE_CONN_START; | 
 | 416 |     pcb->prv_src_uuid = pcb->src_uuid; | 
 | 417 |     pcb->prv_dst_uuid = pcb->dst_uuid; | 
 | 418 |  | 
 | 419 |     pcb->src_uuid     = src_uuid.uu.uuid16; | 
 | 420 |     pcb->dst_uuid     = dst_uuid.uu.uuid16; | 
 | 421 |  | 
 | 422 |     src_uuid.len      = 2; | 
 | 423 |     dst_uuid.len      = 2; | 
 | 424 |  | 
 | 425 |     result = BNEP_Connect (rem_bda, &src_uuid, &dst_uuid, &(pcb->handle)); | 
 | 426 |     if (result != BNEP_SUCCESS) | 
 | 427 |     { | 
 | 428 |         pan_release_pcb (pcb); | 
 | 429 |         return result; | 
 | 430 |     } | 
 | 431 |  | 
 | 432 |     PAN_TRACE_DEBUG1 ("PAN_Connect() current active role set to %d", src_role); | 
 | 433 |     pan_cb.prv_active_role = pan_cb.active_role; | 
 | 434 |     pan_cb.active_role = src_role; | 
 | 435 |     *handle = pcb->handle; | 
 | 436 |     return PAN_SUCCESS; | 
 | 437 | } | 
 | 438 |  | 
 | 439 |  | 
 | 440 |  | 
 | 441 |  | 
 | 442 | /******************************************************************************* | 
 | 443 | ** | 
 | 444 | ** Function         PAN_Disconnect | 
 | 445 | ** | 
 | 446 | ** Description      This is used to disconnect the connection | 
 | 447 | ** | 
 | 448 | ** Parameters:      handle           - handle for the connection | 
 | 449 | ** | 
 | 450 | ** Returns          PAN_SUCCESS      - if the connection is closed successfully | 
 | 451 | **                  PAN_FAILURE      - if the connection is not found or | 
 | 452 | **                                           there is an error in disconnecting | 
 | 453 | ** | 
 | 454 | *******************************************************************************/ | 
 | 455 | tPAN_RESULT PAN_Disconnect (UINT16 handle) | 
 | 456 | { | 
 | 457 |     tPAN_CONN       *pcb; | 
 | 458 |     tBNEP_RESULT    result; | 
 | 459 |  | 
 | 460 |     /* Check if the connection exists */ | 
 | 461 |     pcb = pan_get_pcb_by_handle (handle); | 
 | 462 |     if(!pcb) | 
 | 463 |     { | 
 | 464 |         PAN_TRACE_ERROR1 ("PAN connection not found for the handle %d", handle); | 
 | 465 |         return PAN_FAILURE; | 
 | 466 |     } | 
 | 467 |  | 
 | 468 |     result = BNEP_Disconnect (pcb->handle); | 
| Sharvil Nanavati | 045235e | 2014-01-31 13:39:43 -0800 | [diff] [blame] | 469 |     if (pcb->con_state != PAN_STATE_IDLE) | 
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 470 |         pan_cb.num_conns--; | 
 | 471 |  | 
 | 472 |     if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP) | 
 | 473 |         (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE); | 
 | 474 |  | 
 | 475 |     pan_release_pcb (pcb); | 
 | 476 |  | 
 | 477 |     if (result != BNEP_SUCCESS) | 
 | 478 |     { | 
 | 479 |         PAN_TRACE_EVENT0 ("Error in closing PAN connection"); | 
 | 480 |         return PAN_FAILURE; | 
 | 481 |     } | 
 | 482 |  | 
 | 483 |     PAN_TRACE_EVENT0 ("PAN connection closed"); | 
 | 484 |     return PAN_SUCCESS; | 
 | 485 | } | 
 | 486 |  | 
 | 487 |  | 
 | 488 | /******************************************************************************* | 
 | 489 | ** | 
 | 490 | ** Function         PAN_Write | 
 | 491 | ** | 
 | 492 | ** Description      This sends data over the PAN connections. If this is called | 
 | 493 | **                  on GN or NAP side and the packet is multicast or broadcast | 
 | 494 | **                  it will be sent on all the links. Otherwise the correct link | 
 | 495 | **                  is found based on the destination address and forwarded on it | 
 | 496 | **                  If the return value is not PAN_SUCCESS the application should | 
 | 497 | **                  take care of releasing the message buffer | 
 | 498 | ** | 
 | 499 | ** Parameters:      handle   - handle for the connection | 
 | 500 | **                  dst      - MAC or BD Addr of the destination device | 
 | 501 | **                  src      - MAC or BD Addr of the source who sent this packet | 
 | 502 | **                  protocol - protocol of the ethernet packet like IP or ARP | 
 | 503 | **                  p_data   - pointer to the data | 
 | 504 | **                  len      - length of the data | 
 | 505 | **                  ext      - to indicate that extension headers present | 
 | 506 | ** | 
 | 507 | ** Returns          PAN_SUCCESS       - if the data is sent successfully | 
 | 508 | **                  PAN_FAILURE       - if the connection is not found or | 
 | 509 | **                                           there is an error in sending data | 
 | 510 | ** | 
 | 511 | *******************************************************************************/ | 
 | 512 | tPAN_RESULT PAN_Write (UINT16 handle, BD_ADDR dst, BD_ADDR src, UINT16 protocol, UINT8 *p_data, UINT16 len, BOOLEAN ext) | 
 | 513 | { | 
 | 514 |     tPAN_CONN       *pcb; | 
 | 515 |     UINT16          i; | 
 | 516 |     tBNEP_RESULT    result; | 
 | 517 |  | 
 | 518 |     if (pan_cb.role == PAN_ROLE_INACTIVE || (!(pan_cb.num_conns))) | 
 | 519 |     { | 
 | 520 |         PAN_TRACE_ERROR0 ("PAN is not active Data write failed"); | 
 | 521 |         return PAN_FAILURE; | 
 | 522 |     } | 
 | 523 |  | 
 | 524 |     /* Check if it is broadcast or multicast packet */ | 
 | 525 |     if (dst[0] & 0x01) | 
 | 526 |     { | 
 | 527 |         for (i=0; i<MAX_PAN_CONNS; i++) | 
 | 528 |         { | 
 | 529 |             if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED) | 
 | 530 |                 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); | 
 | 531 |         } | 
 | 532 |  | 
 | 533 |         return PAN_SUCCESS; | 
 | 534 |     } | 
 | 535 |  | 
 | 536 |     if (pan_cb.active_role == PAN_ROLE_CLIENT) | 
 | 537 |     { | 
 | 538 |         /* Data write is on PANU connection */ | 
 | 539 |         for (i=0; i<MAX_PAN_CONNS; i++) | 
 | 540 |         { | 
 | 541 |             if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && | 
 | 542 |                 pan_cb.pcb[i].src_uuid == UUID_SERVCLASS_PANU) | 
 | 543 |                 break; | 
 | 544 |         } | 
 | 545 |  | 
 | 546 |         if (i == MAX_PAN_CONNS) | 
 | 547 |         { | 
 | 548 |             PAN_TRACE_ERROR0 ("PAN Don't have any user connections"); | 
 | 549 |             return PAN_FAILURE; | 
 | 550 |         } | 
 | 551 |  | 
 | 552 |         result = BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); | 
 | 553 |         if (result == BNEP_IGNORE_CMD) | 
 | 554 |         { | 
 | 555 |             PAN_TRACE_DEBUG0 ("PAN ignored data for PANU connection"); | 
 | 556 |             return result; | 
 | 557 |         } | 
 | 558 |         else if (result != BNEP_SUCCESS) | 
 | 559 |         { | 
 | 560 |             PAN_TRACE_ERROR0 ("PAN failed to write data for the PANU connection"); | 
 | 561 |             return result; | 
 | 562 |         } | 
 | 563 |  | 
 | 564 |         PAN_TRACE_DEBUG0 ("PAN successfully wrote data for the PANU connection"); | 
 | 565 |         return PAN_SUCCESS; | 
 | 566 |     } | 
 | 567 |  | 
 | 568 |     pcb = pan_get_pcb_by_handle (handle); | 
 | 569 |     if (!pcb) | 
 | 570 |     { | 
 | 571 |         PAN_TRACE_ERROR0 ("PAN Data write for wrong addr"); | 
 | 572 |         return PAN_FAILURE; | 
 | 573 |     } | 
 | 574 |  | 
 | 575 |     if (pcb->con_state != PAN_STATE_CONNECTED) | 
 | 576 |     { | 
 | 577 |         PAN_TRACE_ERROR0 ("PAN Data write when conn is not active"); | 
 | 578 |         return PAN_FAILURE; | 
 | 579 |     } | 
 | 580 |  | 
 | 581 |     result = BNEP_Write (pcb->handle, dst, p_data, len, protocol, src, ext); | 
 | 582 |     if (result == BNEP_IGNORE_CMD) | 
 | 583 |     { | 
 | 584 |         PAN_TRACE_DEBUG0 ("PAN ignored data write to PANU"); | 
 | 585 |         return result; | 
 | 586 |     } | 
 | 587 |     else if (result != BNEP_SUCCESS) | 
 | 588 |     { | 
 | 589 |         PAN_TRACE_ERROR0 ("PAN failed to send data to the PANU"); | 
 | 590 |         return result; | 
 | 591 |     } | 
 | 592 |  | 
 | 593 |     PAN_TRACE_DEBUG0 ("PAN successfully sent data to the PANU"); | 
 | 594 |     return PAN_SUCCESS; | 
 | 595 | } | 
 | 596 |  | 
 | 597 |  | 
 | 598 | /******************************************************************************* | 
 | 599 | ** | 
 | 600 | ** Function         PAN_WriteBuf | 
 | 601 | ** | 
 | 602 | ** Description      This sends data over the PAN connections. If this is called | 
 | 603 | **                  on GN or NAP side and the packet is multicast or broadcast | 
 | 604 | **                  it will be sent on all the links. Otherwise the correct link | 
 | 605 | **                  is found based on the destination address and forwarded on it | 
 | 606 | **                  If the return value is not PAN_SUCCESS the application should | 
 | 607 | **                  take care of releasing the message buffer | 
 | 608 | ** | 
 | 609 | ** Parameters:      handle   - handle for the connection | 
 | 610 | **                  dst      - MAC or BD Addr of the destination device | 
 | 611 | **                  src      - MAC or BD Addr of the source who sent this packet | 
 | 612 | **                  protocol - protocol of the ethernet packet like IP or ARP | 
 | 613 | **                  p_buf    - pointer to the data buffer | 
 | 614 | **                  ext      - to indicate that extension headers present | 
 | 615 | ** | 
 | 616 | ** Returns          PAN_SUCCESS       - if the data is sent successfully | 
 | 617 | **                  PAN_FAILURE       - if the connection is not found or | 
 | 618 | **                                           there is an error in sending data | 
 | 619 | ** | 
 | 620 | *******************************************************************************/ | 
 | 621 | tPAN_RESULT PAN_WriteBuf (UINT16 handle, BD_ADDR dst, BD_ADDR src, UINT16 protocol, BT_HDR *p_buf, BOOLEAN ext) | 
 | 622 | { | 
 | 623 |     tPAN_CONN       *pcb; | 
 | 624 |     UINT16          i; | 
 | 625 |     tBNEP_RESULT    result; | 
 | 626 |  | 
 | 627 |     /* Check if it is broadcast or multicast packet */ | 
 | 628 |     if (dst[0] & 0x01) | 
 | 629 |     { | 
 | 630 |         UINT8       *p_data; | 
 | 631 |         UINT16      len; | 
 | 632 |  | 
 | 633 |         p_data  = (UINT8 *)(p_buf + 1) + p_buf->offset; | 
 | 634 |         len     = p_buf->len; | 
 | 635 |         PAN_Write (handle, dst, src, protocol, p_data, len, ext); | 
 | 636 |         GKI_freebuf (p_buf); | 
 | 637 |         return PAN_SUCCESS; | 
 | 638 |     } | 
 | 639 |  | 
 | 640 |     if (pan_cb.role == PAN_ROLE_INACTIVE || (!(pan_cb.num_conns))) | 
 | 641 |     { | 
 | 642 |         PAN_TRACE_ERROR0 ("PAN is not active Data write failed"); | 
 | 643 |         GKI_freebuf (p_buf); | 
 | 644 |         return PAN_FAILURE; | 
 | 645 |     } | 
 | 646 |  | 
 | 647 |     /* Check if the data write is on PANU side */ | 
 | 648 |     if (pan_cb.active_role == PAN_ROLE_CLIENT) | 
 | 649 |     { | 
 | 650 |         /* Data write is on PANU connection */ | 
 | 651 |         for (i=0; i<MAX_PAN_CONNS; i++) | 
 | 652 |         { | 
 | 653 |             if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && | 
 | 654 |                 pan_cb.pcb[i].src_uuid == UUID_SERVCLASS_PANU) | 
 | 655 |                 break; | 
 | 656 |         } | 
 | 657 |  | 
 | 658 |         if (i == MAX_PAN_CONNS) | 
 | 659 |         { | 
 | 660 |             PAN_TRACE_ERROR0 ("PAN Don't have any user connections"); | 
 | 661 |             GKI_freebuf (p_buf); | 
 | 662 |             return PAN_FAILURE; | 
 | 663 |         } | 
 | 664 |  | 
 | 665 |         result = BNEP_WriteBuf (pan_cb.pcb[i].handle, dst, p_buf, protocol, src, ext); | 
 | 666 |         if (result == BNEP_IGNORE_CMD) | 
 | 667 |         { | 
 | 668 |             PAN_TRACE_DEBUG0 ("PAN ignored data write for PANU connection"); | 
 | 669 |             return result; | 
 | 670 |         } | 
 | 671 |         else if (result != BNEP_SUCCESS) | 
 | 672 |         { | 
 | 673 |             PAN_TRACE_ERROR0 ("PAN failed to write data for the PANU connection"); | 
 | 674 |             return result; | 
 | 675 |         } | 
 | 676 |  | 
 | 677 |         PAN_TRACE_DEBUG0 ("PAN successfully wrote data for the PANU connection"); | 
 | 678 |         return PAN_SUCCESS; | 
 | 679 |     } | 
 | 680 |  | 
 | 681 |     /* findout to which connection the data is meant for */ | 
 | 682 |     pcb = pan_get_pcb_by_handle (handle); | 
 | 683 |     if (!pcb) | 
 | 684 |     { | 
 | 685 |         PAN_TRACE_ERROR0 ("PAN Buf write for wrong handle"); | 
 | 686 |         GKI_freebuf (p_buf); | 
 | 687 |         return PAN_FAILURE; | 
 | 688 |     } | 
 | 689 |  | 
 | 690 |     if (pcb->con_state != PAN_STATE_CONNECTED) | 
 | 691 |     { | 
 | 692 |         PAN_TRACE_ERROR0 ("PAN Buf write when conn is not active"); | 
 | 693 |         GKI_freebuf (p_buf); | 
 | 694 |         return PAN_FAILURE; | 
 | 695 |     } | 
 | 696 |  | 
 | 697 |     result = BNEP_WriteBuf (pcb->handle, dst, p_buf, protocol, src, ext); | 
 | 698 |     if (result == BNEP_IGNORE_CMD) | 
 | 699 |     { | 
 | 700 |         PAN_TRACE_DEBUG0 ("PAN ignored data buf write to PANU"); | 
 | 701 |         return result; | 
 | 702 |     } | 
 | 703 |     else if (result != BNEP_SUCCESS) | 
 | 704 |     { | 
 | 705 |         PAN_TRACE_ERROR0 ("PAN failed to send data buf to the PANU"); | 
 | 706 |         return result; | 
 | 707 |     } | 
 | 708 |  | 
 | 709 |     PAN_TRACE_DEBUG0 ("PAN successfully sent data buf to the PANU"); | 
 | 710 |     return PAN_SUCCESS; | 
 | 711 | } | 
 | 712 |  | 
 | 713 |  | 
 | 714 | /******************************************************************************* | 
 | 715 | ** | 
 | 716 | ** Function         PAN_SetProtocolFilters | 
 | 717 | ** | 
 | 718 | ** Description      This function is used to set protocol filters on the peer | 
 | 719 | ** | 
 | 720 | ** Parameters:      handle      - handle for the connection | 
 | 721 | **                  num_filters - number of protocol filter ranges | 
 | 722 | **                  start       - array of starting protocol numbers | 
 | 723 | **                  end         - array of ending protocol numbers | 
 | 724 | ** | 
 | 725 | ** | 
 | 726 | ** Returns          PAN_SUCCESS        if protocol filters are set successfully | 
 | 727 | **                  PAN_FAILURE        if connection not found or error in setting | 
 | 728 | ** | 
 | 729 | *******************************************************************************/ | 
 | 730 | tPAN_RESULT PAN_SetProtocolFilters (UINT16 handle, | 
 | 731 |                                     UINT16 num_filters, | 
 | 732 |                                     UINT16 *p_start_array, | 
 | 733 |                                     UINT16 *p_end_array) | 
 | 734 | { | 
 | 735 | #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE) | 
 | 736 |     tPAN_CONN       *pcb; | 
 | 737 |     tPAN_RESULT     result; | 
 | 738 |  | 
 | 739 |     /* Check if the connection exists */ | 
 | 740 |     pcb = pan_get_pcb_by_handle (handle); | 
 | 741 |     if(!pcb) | 
 | 742 |     { | 
 | 743 |         PAN_TRACE_ERROR1 ("PAN connection not found for the handle %d", handle); | 
 | 744 |         return PAN_FAILURE; | 
 | 745 |     } | 
 | 746 |  | 
 | 747 |     result = BNEP_SetProtocolFilters (pcb->handle, num_filters, p_start_array, p_end_array); | 
 | 748 |     if (result != BNEP_SUCCESS) | 
 | 749 |     { | 
 | 750 |         PAN_TRACE_ERROR1 ("PAN failed to set protocol filters for handle %d", handle); | 
 | 751 |         return result; | 
 | 752 |     } | 
 | 753 |  | 
 | 754 |     PAN_TRACE_API1 ("PAN successfully sent protocol filters for handle %d", handle); | 
 | 755 |     return PAN_SUCCESS; | 
 | 756 | #else | 
 | 757 |     return PAN_FAILURE; | 
 | 758 | #endif | 
 | 759 | } | 
 | 760 |  | 
 | 761 |  | 
 | 762 |  | 
 | 763 | /******************************************************************************* | 
 | 764 | ** | 
 | 765 | ** Function         PAN_SetMulticastFilters | 
 | 766 | ** | 
 | 767 | ** Description      This function is used to set multicast filters on the peer | 
 | 768 | ** | 
 | 769 | ** Parameters:      handle      - handle for the connection | 
 | 770 | **                  num_filters - number of multicast filter ranges | 
 | 771 | **                  start       - array of starting multicast filter addresses | 
 | 772 | **                  end         - array of ending multicast filter addresses | 
 | 773 | ** | 
 | 774 | ** | 
 | 775 | ** Returns          PAN_SUCCESS        if multicast filters are set successfully | 
 | 776 | **                  PAN_FAILURE        if connection not found or error in setting | 
 | 777 | ** | 
 | 778 | *******************************************************************************/ | 
 | 779 | tBNEP_RESULT PAN_SetMulticastFilters (UINT16 handle, | 
 | 780 |                                       UINT16 num_mcast_filters, | 
 | 781 |                                       UINT8 *p_start_array, | 
 | 782 |                                       UINT8 *p_end_array) | 
 | 783 | { | 
 | 784 | #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE) | 
 | 785 |     tPAN_CONN       *pcb; | 
 | 786 |     tPAN_RESULT     result; | 
 | 787 |  | 
 | 788 |     /* Check if the connection exists */ | 
 | 789 |     pcb = pan_get_pcb_by_handle (handle); | 
 | 790 |     if(!pcb) | 
 | 791 |     { | 
 | 792 |         PAN_TRACE_ERROR1 ("PAN connection not found for the handle %d", handle); | 
 | 793 |         return PAN_FAILURE; | 
 | 794 |     } | 
 | 795 |  | 
 | 796 |     result = BNEP_SetMulticastFilters (pcb->handle, | 
 | 797 |                             num_mcast_filters, p_start_array, p_end_array); | 
 | 798 |     if (result != BNEP_SUCCESS) | 
 | 799 |     { | 
 | 800 |         PAN_TRACE_ERROR1 ("PAN failed to set multicast filters for handle %d", handle); | 
 | 801 |         return result; | 
 | 802 |     } | 
 | 803 |  | 
 | 804 |     PAN_TRACE_API1 ("PAN successfully sent multicast filters for handle %d", handle); | 
 | 805 |     return PAN_SUCCESS; | 
 | 806 | #else | 
 | 807 |     return PAN_FAILURE; | 
 | 808 | #endif | 
 | 809 | } | 
 | 810 |  | 
 | 811 |  | 
 | 812 | /******************************************************************************* | 
 | 813 | ** | 
 | 814 | ** Function         PAN_SetTraceLevel | 
 | 815 | ** | 
 | 816 | ** Description      This function sets the trace level for PAN. If called with | 
 | 817 | **                  a value of 0xFF, it simply reads the current trace level. | 
 | 818 | ** | 
 | 819 | ** Returns          the new (current) trace level | 
 | 820 | ** | 
 | 821 | *******************************************************************************/ | 
 | 822 | UINT8 PAN_SetTraceLevel (UINT8 new_level) | 
 | 823 | { | 
 | 824 |     if (new_level != 0xFF) | 
 | 825 |         pan_cb.trace_level = new_level; | 
 | 826 |     else | 
 | 827 |         pan_dump_status (); | 
 | 828 |  | 
 | 829 |     return (pan_cb.trace_level); | 
 | 830 | } | 
 | 831 |  | 
 | 832 | /******************************************************************************* | 
 | 833 | ** | 
 | 834 | ** Function         PAN_Init | 
 | 835 | ** | 
 | 836 | ** Description      This function initializes the PAN module variables | 
 | 837 | ** | 
 | 838 | ** Parameters:      none | 
 | 839 | ** | 
 | 840 | ** Returns          none | 
 | 841 | ** | 
 | 842 | *******************************************************************************/ | 
 | 843 | void PAN_Init (void) | 
 | 844 | { | 
 | 845 |     memset (&pan_cb, 0, sizeof (tPAN_CB)); | 
 | 846 |  | 
 | 847 | #if defined(PAN_INITIAL_TRACE_LEVEL) | 
 | 848 |     pan_cb.trace_level = PAN_INITIAL_TRACE_LEVEL; | 
 | 849 | #else | 
 | 850 |     pan_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */ | 
 | 851 | #endif | 
 | 852 | } | 
 | 853 |  | 
 | 854 |  |