OSDN Git Service

Use std::queue for pending_enc_clcb
authorJakub Pawlowski <jpawlowski@google.com>
Tue, 30 May 2017 16:59:54 +0000 (09:59 -0700)
committerJakub Pawlowski <jpawlowski@google.com>
Sat, 3 Jun 2017 00:48:39 +0000 (17:48 -0700)
Test: 62188929
Change-Id: Ide07f15c5e5b6bc8b93ac350081b7bef7c7b3938

stack/gatt/gatt_auth.cc
stack/gatt/gatt_int.h
stack/gatt/gatt_main.cc
stack/gatt/gatt_utils.cc

index 82b03a6..d970837 100644 (file)
@@ -94,7 +94,7 @@ static bool gatt_sign_data(tGATT_CLCB* p_clcb) {
 void gatt_verify_signature(tGATT_TCB* p_tcb, BT_HDR* p_buf) {
   uint16_t cmd_len;
   uint8_t op_code;
-  uint8_t *p, *p_orig = (uint8_t *)(p_buf + 1) + p_buf->offset;
+  uint8_t *p, *p_orig = (uint8_t*)(p_buf + 1) + p_buf->offset;
   uint32_t counter;
 
   if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) {
@@ -128,8 +128,7 @@ void gatt_verify_signature(tGATT_TCB* p_tcb, BT_HDR* p_buf) {
  ******************************************************************************/
 void gatt_sec_check_complete(bool sec_check_ok, tGATT_CLCB* p_clcb,
                              uint8_t sec_act) {
-  if (p_clcb && p_clcb->p_tcb &&
-      fixed_queue_is_empty(p_clcb->p_tcb->pending_enc_clcb)) {
+  if (p_clcb && p_clcb->p_tcb && p_clcb->p_tcb->pending_enc_clcb.empty()) {
     gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_NONE);
   }
 
@@ -152,48 +151,44 @@ void gatt_sec_check_complete(bool sec_check_ok, tGATT_CLCB* p_clcb,
  ******************************************************************************/
 void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
                          UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
-  tGATT_TCB* p_tcb;
-  uint8_t sec_flag;
+  GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
+  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
+  if (!p_tcb) {
+    GATT_TRACE_ERROR("%s: enc callback for unknown bd_addr", __func__);
+    return;
+  }
+
+  if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) return;
+
+  if (p_tcb->pending_enc_clcb.empty()) {
+    GATT_TRACE_ERROR("%s: no operation waiting for encrypting", __func__);
+    return;
+  }
+
+  tGATT_CLCB* p_clcb = p_tcb->pending_enc_clcb.front();
+  p_tcb->pending_enc_clcb.pop();
+
   bool status = false;
+  if (result == BTM_SUCCESS) {
+    if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM) {
+      uint8_t sec_flag = 0;
+      BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
 
-  GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
-  p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
-  if (p_tcb != NULL) {
-    if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) return;
-
-    tGATT_PENDING_ENC_CLCB* p_buf =
-        (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
-            p_tcb->pending_enc_clcb);
-    if (p_buf != NULL) {
-      if (result == BTM_SUCCESS) {
-        if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM) {
-          BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
-
-          if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
-            status = true;
-          }
-        } else {
-          status = true;
-        }
-      }
-      gatt_sec_check_complete(status, p_buf->p_clcb, p_tcb->sec_act);
-      osi_free(p_buf);
-      /* start all other pending operation in queue */
-      for (size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
-           count > 0; count--) {
-        p_buf = (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
-            p_tcb->pending_enc_clcb);
-        if (p_buf != NULL) {
-          gatt_security_check_start(p_buf->p_clcb);
-          osi_free(p_buf);
-        } else
-          break;
+      if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
+        status = true;
       }
     } else {
-      GATT_TRACE_ERROR("Unknown operation encryption completed");
+      status = true;
     }
-  } else {
-    GATT_TRACE_ERROR("enc callback for unknown bd_addr");
+  }
+
+  gatt_sec_check_complete(status, p_clcb, p_tcb->sec_act);
+
+  /* start all other pending operation in queue */
+  while (!p_tcb->pending_enc_clcb.empty()) {
+    tGATT_CLCB* p_clcb = p_tcb->pending_enc_clcb.front();
+    p_tcb->pending_enc_clcb.pop();
+    gatt_security_check_start(p_clcb);
   }
 }
 
@@ -208,37 +203,28 @@ void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
  *
  ******************************************************************************/
 void gatt_notify_enc_cmpl(BD_ADDR bd_addr) {
-  tGATT_TCB* p_tcb;
-  uint8_t i = 0;
-
-  p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
-  if (p_tcb != NULL) {
-    for (i = 0; i < GATT_MAX_APPS; i++) {
-      if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb) {
-        (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if,
-                                                  bd_addr);
-      }
+  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
+  if (!p_tcb) {
+    GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
+    return;
+  }
+
+  for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+    if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb) {
+      (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if,
+                                                bd_addr);
     }
+  }
 
-    if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) {
-      gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
-
-      size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
-      for (; count > 0; count--) {
-        tGATT_PENDING_ENC_CLCB* p_buf =
-            (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
-                p_tcb->pending_enc_clcb);
-        if (p_buf != NULL) {
-          gatt_security_check_start(p_buf->p_clcb);
-          osi_free(p_buf);
-        } else
-          break;
-      }
+  if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) {
+    gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
+
+    while (!p_tcb->pending_enc_clcb.empty()) {
+      tGATT_CLCB* p_clcb = p_tcb->pending_enc_clcb.front();
+      p_tcb->pending_enc_clcb.pop();
+      gatt_security_check_start(p_clcb);
     }
-  } else {
-    GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
   }
-  return;
 }
 /*******************************************************************************
  *
@@ -270,16 +256,10 @@ tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB* p_tcb) {
   }
   return sec_act;
 }
-/*******************************************************************************
- *
- * Function         gatt_determine_sec_act
- *
- * Description      This routine determine the security action based on
- *                  auth_request and current link status
- *
- * Returns          tGATT_SEC_ACTION security action
- *
- ******************************************************************************/
+/**
+ * This routine determine the security action based on auth_request and current
+ * link status. Returns tGATT_SEC_ACTION (security action)
+ */
 tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB* p_clcb) {
   tGATT_SEC_ACTION act = GATT_SEC_OK;
   uint8_t sec_flag;
@@ -455,10 +435,10 @@ bool gatt_security_check_start(tGATT_CLCB* p_clcb) {
           status = false;
         }
       }
-      if (status) gatt_add_pending_enc_channel_clcb(p_tcb, p_clcb);
+      if (status) p_tcb->pending_enc_clcb.push(p_clcb);
       break;
     case GATT_SEC_ENC_PENDING:
-      gatt_add_pending_enc_channel_clcb(p_tcb, p_clcb);
+      p_tcb->pending_enc_clcb.push(p_clcb);
       /* wait for link encrypotion to finish */
       break;
     default:
index d81b252..127ecf4 100644 (file)
@@ -260,8 +260,10 @@ typedef struct {
   bool is_primary;
 } tGATT_SRV_LIST_ELEM;
 
+struct tGATT_CLCB;
+
 typedef struct {
-  fixed_queue_t* pending_enc_clcb; /* pending encryption channel q */
+  std::queue<tGATT_CLCB*> pending_enc_clcb; /* pending encryption channel q */
   tGATT_SEC_ACTION sec_act;
   BD_ADDR peer_bda;
   tBT_TRANSPORT transport;
@@ -302,7 +304,7 @@ typedef struct {
   tGATT_DISC_RES result;
   bool wait_for_read_rsp;
 } tGATT_READ_INC_UUID128;
-typedef struct {
+struct tGATT_CLCB {
   tGATT_TCB* p_tcb; /* associated TCB of this CLCB */
   tGATT_REG* p_reg; /* owner of this CLCB */
   uint8_t sccb_idx;
@@ -323,10 +325,7 @@ typedef struct {
   bool in_use;
   alarm_t* gatt_rsp_timer_ent; /* peer response timer */
   uint8_t retry_count;
-
-} tGATT_CLCB;
-
-typedef struct { tGATT_CLCB* p_clcb; } tGATT_PENDING_ENC_CLCB;
+};
 
 typedef struct {
   uint16_t handle;
@@ -458,8 +457,6 @@ extern tGATT_STATUS gatt_send_error_rsp(tGATT_TCB* p_tcb, uint8_t err_code,
                                         uint8_t op_code, uint16_t handle,
                                         bool deq);
 extern void gatt_dbg_display_uuid(tBT_UUID bt_uuid);
-extern tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(
-    tGATT_TCB* p_tcb, tGATT_CLCB* p_clcb);
 
 extern bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb);
 extern tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(BD_ADDR bda);
index 2eb9c04..b6e68f8 100644 (file)
@@ -95,7 +95,7 @@ void gatt_init(void) {
 
   GATT_TRACE_DEBUG("gatt_init()");
 
-  memset(&gatt_cb, 0, sizeof(tGATT_CB));
+  gatt_cb = tGATT_CB();
   memset(&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));
 
 #if defined(GATT_INITIAL_TRACE_LEVEL)
@@ -158,8 +158,7 @@ void gatt_free(void) {
   fixed_queue_free(gatt_cb.srv_chg_clt_q, NULL);
   gatt_cb.srv_chg_clt_q = NULL;
   for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
-    fixed_queue_free(gatt_cb.tcb[i].pending_enc_clcb, NULL);
-    gatt_cb.tcb[i].pending_enc_clcb = NULL;
+    gatt_cb.tcb[i].pending_enc_clcb = std::queue<tGATT_CLCB*>();
 
     fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
     gatt_cb.tcb[i].pending_ind_q = NULL;
@@ -375,9 +374,8 @@ bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
     if (p_tcb != NULL) {
       if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys)) {
         GATT_TRACE_ERROR("gatt_connect failed");
-        fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
         fixed_queue_free(p_tcb->pending_ind_q, NULL);
-        memset(p_tcb, 0, sizeof(tGATT_TCB));
+        *p_tcb = tGATT_TCB();
       } else
         ret = true;
     } else {
index 5f1f316..c1770a9 100644 (file)
@@ -102,27 +102,6 @@ void gatt_free_pending_ind(tGATT_TCB* p_tcb) {
 
 /*******************************************************************************
  *
- * Function         gatt_free_pending_enc_queue
- *
- * Description       Free all buffers in pending encyption queue
- *
- * Returns       None
- *
- ******************************************************************************/
-void gatt_free_pending_enc_queue(tGATT_TCB* p_tcb) {
-  GATT_TRACE_DEBUG("%s", __func__);
-
-  if (p_tcb->pending_enc_clcb == NULL) return;
-
-  /* release all queued indications */
-  while (!fixed_queue_is_empty(p_tcb->pending_enc_clcb))
-    osi_free(fixed_queue_try_dequeue(p_tcb->pending_enc_clcb));
-  fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
-  p_tcb->pending_enc_clcb = NULL;
-}
-
-/*******************************************************************************
- *
  * Function         gatt_delete_dev_from_srv_chg_clt_list
  *
  * Description    Delete a device from the service changed client lit
@@ -449,26 +428,7 @@ tGATT_TCB* gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) {
 
   return p_tcb;
 }
-/*******************************************************************************
- *
- * Function         gatt_find_i_tcb_free
- *
- * Description      Search for an empty tcb entry, and return the index.
- *
- * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
- *
- ******************************************************************************/
-uint8_t gatt_find_i_tcb_free(void) {
-  uint8_t i = 0, j = GATT_INDEX_INVALID;
 
-  for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
-    if (!gatt_cb.tcb[i].in_use) {
-      j = i;
-      break;
-    }
-  }
-  return j;
-}
 /*******************************************************************************
  *
  * Function         gatt_allocate_tcb_by_bdaddr
@@ -479,33 +439,28 @@ uint8_t gatt_find_i_tcb_free(void) {
  *
  ******************************************************************************/
 tGATT_TCB* gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) {
-  uint8_t i = 0;
-  bool allocated = false;
-  tGATT_TCB* p_tcb = NULL;
-
   /* search for existing tcb with matching bda    */
-  i = gatt_find_i_tcb_by_addr(bda, transport);
+  uint8_t j = gatt_find_i_tcb_by_addr(bda, transport);
+  if (j != GATT_INDEX_INVALID) return &gatt_cb.tcb[j];
+
   /* find free tcb */
-  if (i == GATT_INDEX_INVALID) {
-    i = gatt_find_i_tcb_free();
-    allocated = true;
-  }
-  if (i != GATT_INDEX_INVALID) {
-    p_tcb = &gatt_cb.tcb[i];
-
-    if (allocated) {
-      memset(p_tcb, 0, sizeof(tGATT_TCB));
-      p_tcb->pending_enc_clcb = fixed_queue_new(SIZE_MAX);
-      p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
-      p_tcb->conf_timer = alarm_new("gatt.conf_timer");
-      p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer");
-      p_tcb->in_use = true;
-      p_tcb->tcb_idx = i;
-      p_tcb->transport = transport;
-    }
+  for (int i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
+    tGATT_TCB* p_tcb = &gatt_cb.tcb[i];
+    if (p_tcb->in_use) continue;
+
+    *p_tcb = tGATT_TCB();
+
+    p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
+    p_tcb->conf_timer = alarm_new("gatt.conf_timer");
+    p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer");
+    p_tcb->in_use = true;
+    p_tcb->tcb_idx = i;
+    p_tcb->transport = transport;
     memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
+    return p_tcb;
   }
-  return p_tcb;
+
+  return NULL;
 }
 
 /*******************************************************************************
@@ -1608,7 +1563,6 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, uint16_t reason,
     alarm_free(p_tcb->conf_timer);
     p_tcb->conf_timer = NULL;
     gatt_free_pending_ind(p_tcb);
-    gatt_free_pending_enc_queue(p_tcb);
     fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
     p_tcb->sr_cmd.multi_rsp_q = NULL;
 
@@ -1622,7 +1576,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, uint16_t reason,
                                    transport);
       }
     }
-    memset(p_tcb, 0, sizeof(tGATT_TCB));
+    *p_tcb = tGATT_TCB();
   }
   GATT_TRACE_DEBUG("exit gatt_cleanup_upon_disc ");
 }
@@ -1991,26 +1945,3 @@ bool gatt_update_auto_connect_dev(tGATT_IF gatt_if, bool add, BD_ADDR bd_addr) {
   }
   return ret;
 }
-
-/*******************************************************************************
- *
- * Function     gatt_add_pending_new_srv_start
- *
- * Description  Add a pending new srv start to the new service start queue
- *
- * Returns    Pointer to the new service start buffer, NULL no buffer available
- *
- ******************************************************************************/
-tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB* p_tcb,
-                                                          tGATT_CLCB* p_clcb) {
-  tGATT_PENDING_ENC_CLCB* p_buf =
-      (tGATT_PENDING_ENC_CLCB*)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB));
-
-  GATT_TRACE_DEBUG("%s", __func__);
-  GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb");
-
-  p_buf->p_clcb = p_clcb;
-  fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf);
-
-  return p_buf;
-}