]> granicus.if.org Git - esp-idf/commitdiff
Merge branch 'docs/sdio_slave_protocol_comb' into 'master'
authorIvan Grokhotkov <ivan@espressif.com>
Tue, 26 Jun 2018 11:36:08 +0000 (19:36 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Tue, 26 Jun 2018 11:36:08 +0000 (19:36 +0800)
doc(sdio_slave): add some information of slave protocol

See merge request idf/esp-idf!2598

14 files changed:
components/bt/bluedroid/common/include/common/bt_target.h
components/bt/bluedroid/device/controller.c
components/bt/bluedroid/hci/hci_hal_h4.c
components/bt/bluedroid/hci/hci_layer.c
components/bt/bluedroid/hci/hci_packet_factory.c
components/bt/bluedroid/hci/include/hci/hci_packet_factory.h
components/bt/bluedroid/stack/include/stack/hcidefs.h
components/bt/bluedroid/stack/l2cap/include/l2c_int.h
components/bt/bluedroid/stack/l2cap/l2c_utils.c
components/bt/lib
components/esp32/include/esp_mesh_internal.h
components/esp32/lib
examples/mesh/internal_communication/main/mesh_main.c
examples/mesh/manual_networking/README.md [new file with mode: 0644]

index ef45566867b7266eb847e0de02ede60bc92a86e7..a5bb49b6c8ef677e9681d246ecf015b0f18d3054 100644 (file)
 #define BTM_DEFAULT_DISC_INTERVAL   0x0800
 #endif
 
-/* 
+/*
 * {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS}
 *
 * SERVICE_CLASS:0x5A (Bit17 -Networking,Bit19 - Capturing,Bit20 -Object Transfer,Bit22 -Telephony)
 #define BTM_BLE_CONFORMANCE_TESTING           FALSE
 #endif
 
+/******************************************************************************
+**
+** CONTROLLER TO HOST FLOW CONTROL
+**
+******************************************************************************/
+
+#define C2H_FLOW_CONTROL_INCLUDED TRUE
+
 /******************************************************************************
 **
 ** L2CAP
index 06b8a52c7c6a8a68da00eadf91f72729fbcd7cde..a748f0f530f7e423966be3c4ccb58026ba741a8e 100644 (file)
@@ -95,6 +95,12 @@ static void start_up(void)
         response, &acl_data_size_classic, &acl_buffer_count_classic,
         &sco_data_size, &sco_buffer_count);
 
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+    // Enable controller to host flow control
+    response = AWAIT_COMMAND(packet_factory->make_set_c2h_flow_control(HCI_HOST_FLOW_CTRL_ACL_ON));
+    packet_parser->parse_generic_command_complete(response);
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
     // Tell the controller about our buffer sizes and buffer counts next
     // TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?
     response = AWAIT_COMMAND(
index 8b87a6faa01ee8ac5e7e70e9c3d4a8460fb75669..0a93f1d0c7c2b6a88ecbc7468bc7ed394b09721a 100644 (file)
 #include "osi/thread.h"
 #include "esp_bt.h"
 
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+#include "l2c_int.h"
+#include "stack/hcimsgs.h"
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
 #define HCI_HAL_SERIAL_BUFFER_SIZE 1026
 #define HCI_BLE_EVENT 0x3e
 #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
@@ -165,6 +170,7 @@ static void hci_hal_h4_rx_handler(void *arg)
         if (pdTRUE == xQueueReceive(xHciH4Queue, &e, (portTickType)portMAX_DELAY)) {
             if (e.sig == SIG_HCI_HAL_RECV_PACKET) {
                 fixed_queue_process(hci_hal_env.rx_q);
+
             }
         }
     }
@@ -185,6 +191,37 @@ task_post_status_t hci_hal_h4_task_post(task_post_t timeout)
     return TASK_POST_FAIL;
 }
 
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+static void hci_packet_complete(BT_HDR *packet){
+    uint8_t type, num_handle;
+    uint16_t handle;
+    uint16_t handles[MAX_L2CAP_LINKS + 4];
+    uint16_t num_packets[MAX_L2CAP_LINKS + 4];
+    uint8_t *stream = packet->data + packet->offset;
+    tL2C_LCB  *p_lcb = NULL;
+
+    STREAM_TO_UINT8(type, stream);
+    if (type == DATA_TYPE_ACL/* || type == DATA_TYPE_SCO*/) {
+        STREAM_TO_UINT16(handle, stream);
+        handle = handle & HCI_DATA_HANDLE_MASK;
+        p_lcb = l2cu_find_lcb_by_handle(handle);
+        if (p_lcb) {
+            p_lcb->completed_packets++;
+        }
+        if (esp_vhci_host_check_send_available()){
+            num_handle = l2cu_find_completed_packets(handles, num_packets);
+            if (num_handle > 0){
+                btsnd_hcic_host_num_xmitted_pkts (num_handle, handles, num_packets);
+            }
+        } else {
+            //Send HCI_Host_Number_of_Completed_Packets next time.
+        }
+
+    }
+}
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
+
 static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
 {
     uint8_t type, hdr_size;
@@ -194,6 +231,11 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
     if (!packet) {
         return;
     }
+
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+    hci_packet_complete(packet);
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
     STREAM_TO_UINT8(type, stream);
     packet->offset++;
     packet->len--;
index 59b08c48104af0e0578f129253f1d4236a6fc2a9..ec68663864948b580e2e79fea8632f682e0dbc8a 100644 (file)
@@ -274,6 +274,7 @@ static void transmit_command(
 
     fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
     hci_host_task_post(TASK_POST_BLOCKING);
+
 }
 
 static future_t *transmit_command_futured(BT_HDR *command)
@@ -317,8 +318,14 @@ static void event_command_ready(fixed_queue_t *queue)
     command_waiting_response_t *cmd_wait_q = &hci_host_env.cmd_waiting_q;
 
     wait_entry = fixed_queue_dequeue(queue);
-    hci_host_env.command_credits--;
 
+    if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE){
+        packet_fragmenter->fragment_and_dispatch(wait_entry->command);
+        buffer_allocator->free(wait_entry->command);
+        osi_free(wait_entry);
+        return;
+    }
+    hci_host_env.command_credits--;
     // Move it to the list of commands awaiting response
     osi_mutex_lock(&cmd_wait_q->commands_pending_response_lock, OSI_MUTEX_MAX_TIMEOUT);
     list_append(cmd_wait_q->commands_pending_response, wait_entry);
@@ -435,7 +442,6 @@ static bool filter_incoming_event(BT_HDR *packet)
     if (event_code == HCI_COMMAND_COMPLETE_EVT) {
         STREAM_TO_UINT8(hci_host_env.command_credits, stream);
         STREAM_TO_UINT16(opcode, stream);
-
         wait_entry = get_waiting_command(opcode);
         if (!wait_entry) {
             HCI_TRACE_WARNING("%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode);
index 2c88570e3de36554ea1a94dcf07db876e9ca511a..ae204caf4754e8e35b3041ea7cbdea416bddf3ee 100644 (file)
@@ -45,6 +45,16 @@ static BT_HDR *make_read_buffer_size(void)
     return make_command_no_params(HCI_READ_BUFFER_SIZE);
 }
 
+static BT_HDR *make_set_c2h_flow_control(uint8_t enable)
+{
+    uint8_t *stream;
+    const uint8_t parameter_size = 1;
+    BT_HDR *packet = make_command(HCI_SET_HC_TO_HOST_FLOW_CTRL, parameter_size, &stream);
+
+    UINT8_TO_STREAM(stream, enable);
+    return packet;
+}
+
 static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count)
 {
     uint8_t *stream;
@@ -220,6 +230,7 @@ static BT_HDR *make_packet(size_t data_size)
 static const hci_packet_factory_t interface = {
     make_reset,
     make_read_buffer_size,
+    make_set_c2h_flow_control,
     make_host_buffer_size,
     make_read_local_version_info,
     make_read_bd_addr,
index 0cc4dc6849e87b221574ef059b6bdf2a29c4553e..e48c4be437c9b05bfffebd05d5605e8701f4377e 100644 (file)
@@ -25,6 +25,7 @@
 typedef struct {
     BT_HDR *(*make_reset)(void);
     BT_HDR *(*make_read_buffer_size)(void);
+    BT_HDR *(*make_set_c2h_flow_control)(uint8_t enable);
     BT_HDR *(*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count);
     BT_HDR *(*make_read_local_version_info)(void);
     BT_HDR *(*make_read_bd_addr)(void);
index 09320b1f1aa738be6ef3762ccad64e98f4c6d75e..0169ba8cc32a62f9c2154ff614022e2fb4522a0f 100644 (file)
 #define HCI_ERR_MAX_ERR                                 0x43
 
 //ESP vendor error code
-#define HCI_ERR_ESP_VENDOR_FAIL                         0xE0               
+#define HCI_ERR_ESP_VENDOR_FAIL                         0xE0
 
 #define HCI_HINT_TO_RECREATE_AMP_PHYS_LINK              0xFF
 
index 3699e7f05bcf062a9c9924f83cfa1f4bc3c6bb20..e2c0ef6a760e3a7252493e7f5749bf201e510b24 100644 (file)
@@ -376,6 +376,7 @@ typedef struct t_l2c_linkcb {
 
     TIMER_LIST_ENT      timer_entry;                /* Timer list entry for timeout evt */
     UINT16              handle;                     /* The handle used with LM          */
+    UINT16              completed_packets;          /* The number of conpleted packets  */
 
     tL2C_CCB_Q          ccb_queue;                  /* Queue of CCBs on this LCB        */
 
@@ -667,6 +668,10 @@ extern void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb);
 
 #endif
 
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+extern UINT8 l2cu_find_completed_packets(UINT16 *handles, UINT16 *num_packets);
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
 extern BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr);
 extern void    l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb);
 extern void    l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb);
index 358a57b5f4d557bf9f4280570a92438f6c18724e..b1cfbe46ddbaeaaeb325d2ce11880f3c5bb88c7e 100644 (file)
@@ -57,7 +57,7 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
             btu_free_timer(&p_lcb->timer_entry);
             btu_free_timer(&p_lcb->info_timer_entry);
             btu_free_timer(&p_lcb->upda_con_timer);
-            
+
             memset (p_lcb, 0, sizeof (tL2C_LCB));
             memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
 
@@ -86,6 +86,9 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
                 l2c_link_adjust_allocation();
             }
             p_lcb->link_xmit_data_q = list_new(NULL);
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+            p_lcb->completed_packets = 0;
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
             return (p_lcb);
         }
     }
@@ -137,7 +140,7 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
     memset(&p_lcb->info_timer_entry, 0, sizeof(TIMER_LIST_ENT));
     btu_free_timer(&p_lcb->upda_con_timer);
     memset(&p_lcb->upda_con_timer, 0, sizeof(TIMER_LIST_ENT));
-        
+
     /* Release any unfinished L2CAP packet on this link */
     if (p_lcb->p_hcit_rcv_acl) {
         osi_free(p_lcb->p_hcit_rcv_acl);
@@ -250,6 +253,11 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
         fixed_queue_free(p_lcb->le_sec_pending_q, NULL);
         p_lcb->le_sec_pending_q = NULL;
     }
+
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+    p_lcb->completed_packets = 0;
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+
 }
 
 
@@ -1488,7 +1496,7 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
     btu_free_quick_timer(&p_ccb->fcrb.ack_timer);
     memset(&p_ccb->fcrb.ack_timer, 0, sizeof(TIMER_LIST_ENT));
     p_ccb->fcrb.ack_timer.param  = (TIMER_PARAM_TYPE)p_ccb;
-    
+
     btu_free_quick_timer(&p_ccb->fcrb.mon_retrans_timer);
     memset(&p_ccb->fcrb.mon_retrans_timer, 0, sizeof(TIMER_LIST_ENT));
     p_ccb->fcrb.mon_retrans_timer.param  = (TIMER_PARAM_TYPE)p_ccb;
@@ -3140,6 +3148,35 @@ void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb)
 
 #endif /* BLE_INCLUDED == TRUE */
 
+#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function         l2cu_find_completed_packets
+**
+** Description      Find the completed packets,
+**                  Then set it to zero
+**
+** Returns          The num of handles
+**
+*******************************************************************************/
+UINT8 l2cu_find_completed_packets(UINT16 *handles, UINT16 *num_packets)
+{
+    int         xx;
+    UINT8       num = 0;
+    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
+
+    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
+        if ((p_lcb->in_use) && (p_lcb->completed_packets > 0)) {
+            *(handles++) = p_lcb->handle;
+            *(num_packets++) = p_lcb->completed_packets;
+            num++;
+            p_lcb->completed_packets = 0;
+        }
+    }
+
+    return num;
+}
+#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
 
 /*******************************************************************************
 ** Functions used by both Full and Light Stack
index a3070a4a8c4dddc4dcb13576e468f424d78c598e..2e3296c0ad97117bf9ce97e5f1330ec0077bfe4f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a3070a4a8c4dddc4dcb13576e468f424d78c598e
+Subproject commit 2e3296c0ad97117bf9ce97e5f1330ec0077bfe4f
index da349297ebb75ad73c07d526cb827b3b22eb58ec..36bc2dc9045066940f9fa110855e55e55b4aa76f 100644 (file)
@@ -43,12 +43,23 @@ typedef struct {
 typedef struct {
     int duration_ms;   /* parent weak RSSI monitor duration, if the RSSI continues to be weak during this duration_ms,
                           will switch to a better parent */
-    int cnx_rssi;      /* RSSI threshold for keeping a good connection with parent */
+    int cnx_rssi;      /* RSSI threshold for keeping a good connection with parent.
+                          if set a value greater than -120 dBm, will arm a timer to monitor current RSSI at a period time of
+                          duration_ms. if keep the default value(-120 dBm), a timer at a random period(<3minutes) will
+                          be armed to switch a better parent if there does have one.
+                          The better parent must have RSSI greater than a high RSSI threshold(-78 dBm by default) and a top layer
+                          than current one. */
     int select_rssi;   /* RSSI threshold for parent selection, should be a value greater than switch_rssi */
-    int switch_rssi;   /* RSSI threshold for action to reselect a better parent */
+    int switch_rssi;   /* Disassociate current parent and switch to a new parent when the RSSI is greater than this set threshold */
     int backoff_rssi;  /* RSSI threshold for connecting to the root */
 } mesh_switch_parent_t;
 
+typedef struct {
+    int high;
+    int medium;
+    int low;
+} mesh_rssi_threshold_t;
+
 /**
  * @brief mesh networking IE
  */
@@ -74,13 +85,13 @@ typedef struct {
     uint16_t self_cap;       /**< self capacity */
     uint16_t layer2_cap;     /**< layer2 capacity */
     uint16_t scan_ap_num;    /**< the number of scanned APs */
-    int8_t rssi;             /**< rssi of the parent */
-    int8_t router_rssi;      /**< rssi of the router */
+    int8_t rssi;             /**< RSSI of the parent */
+    int8_t router_rssi;      /**< RSSI of the router */
     uint8_t flag;            /**< flag of networking */
     uint8_t rc_addr[6];      /**< root address */
-    int8_t rc_rssi;          /**< root rssi */
+    int8_t rc_rssi;          /**< root RSSI */
     uint8_t vote_addr[6];    /**< voter address */
-    int8_t vote_rssi;        /**< vote rssi of the router */
+    int8_t vote_rssi;        /**< vote RSSI of the router */
     uint8_t vote_ttl;        /**< vote ttl */
     uint16_t votes;          /**< votes */
     uint16_t my_votes;       /**< my votes */
@@ -132,7 +143,7 @@ esp_err_t esp_mesh_set_attempts(mesh_attempts_t *attempts);
  *
  * @return
  *    - ESP_OK
- *    - ESP_FAIL
+ *    - ESP_ERR_MESH_ARGUMENT
  */
 esp_err_t esp_mesh_get_attempts(mesh_attempts_t *attempts);
 
@@ -143,7 +154,7 @@ esp_err_t esp_mesh_get_attempts(mesh_attempts_t *attempts);
  *
  * @return
  *    - ESP_OK
- *    - ESP_FAIL
+ *    - ESP_ERR_MESH_ARGUMENT
  */
 esp_err_t esp_mesh_set_switch_parent_paras(mesh_switch_parent_t *paras);
 
@@ -154,10 +165,46 @@ esp_err_t esp_mesh_set_switch_parent_paras(mesh_switch_parent_t *paras);
  *
  * @return
  *    - ESP_OK
- *    - ESP_FAIL
+ *    - ESP_ERR_MESH_ARGUMENT
  */
 esp_err_t esp_mesh_get_switch_parent_paras(mesh_switch_parent_t *paras);
 
+/**
+ * @brief     set RSSI threshold
+ *            The default high RSSI threshold value is -78 dBm.
+ *            The default medium RSSI threshold value is -82 dBm.
+ *            The default low RSSI threshold value is -85 dBm.
+ *
+ * @param     threshold  RSSI threshold
+ *
+ * @return
+ *    - ESP_OK
+ *    - ESP_ERR_MESH_ARGUMENT
+ */
+esp_err_t esp_mesh_set_rssi_threshold(const mesh_rssi_threshold_t *threshold);
+
+/**
+ * @brief     get RSSI threshold
+ * @param     threshold  RSSI threshold
+ *
+ * @return
+ *    - ESP_OK
+ *    - ESP_ERR_MESH_ARGUMENT
+ */
+esp_err_t esp_mesh_get_rssi_threshold(mesh_rssi_threshold_t *threshold);
+
+/**
+ * @brief     enable the minimum rate to 6Mbps
+ *
+ * @attention This API shall be called before WiFi start.
+ *
+ * @param     is_6m  enable or not
+ *
+ * @return
+ *    - ESP_OK
+ */
+esp_err_t esp_mesh_set_6m_rate(bool is_6m);
+
 /**
  * @brief     print the number of txQ waiting
  *
@@ -195,6 +242,29 @@ esp_err_t esp_mesh_set_passive_scan_time(int time_ms);
  */
 int esp_mesh_get_passive_scan_time(void);
 
+/**
+ * @brief     set announce interval
+ *            The default short interval is 500 milliseconds.
+ *            The default long interval is 3000 milliseconds.
+ *
+ * @param     short_ms  shall be greater than the default value
+ * @param     long_ms  shall be greater than the default value
+ *
+ * @return
+ *    - ESP_OK
+ */
+esp_err_t esp_mesh_set_announce_interval(int short_ms, int long_ms);
+
+/**
+ * @brief     get announce interval
+ *
+ * @param     short_ms  short interval
+ * @param     long_ms  long interval
+ *
+ * @return
+ *    - ESP_OK
+ */
+esp_err_t esp_mesh_get_announce_interval(int *short_ms, int *long_ms);
 
 #ifdef __cplusplus
 }
index 67fe3bdfb2f82b1befed076c659951bc03a54eed..1f2b30fc41b17d1fe8cca26e90d5665f212bfaa9 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 67fe3bdfb2f82b1befed076c659951bc03a54eed
+Subproject commit 1f2b30fc41b17d1fe8cca26e90d5665f212bfaa9
index acbfe6431dcd0ea37e2c02cc236da7c4f8552aaa..4e6b10901f6d1fc8e074c56e3557118fb6f10c2b 100644 (file)
@@ -372,14 +372,6 @@ void app_main(void)
     memcpy((uint8_t *) &cfg.mesh_ap.password, CONFIG_MESH_AP_PASSWD,
            strlen(CONFIG_MESH_AP_PASSWD));
     ESP_ERROR_CHECK(esp_mesh_set_config(&cfg));
-    /* set RSSI threshold for connecting to the root */
-    mesh_switch_parent_t switch_paras ;
-    ESP_ERROR_CHECK(esp_mesh_get_switch_parent_paras(&switch_paras));
-    switch_paras.select_rssi = -55;
-    switch_paras.cnx_rssi = -65;
-    switch_paras.duration_ms = 120 * 1000;
-    switch_paras.switch_rssi = -65;
-    ESP_ERROR_CHECK(esp_mesh_set_switch_parent_paras(&switch_paras));
     /* mesh start */
     ESP_ERROR_CHECK(esp_mesh_start());
     ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d, %s\n",  esp_get_free_heap_size(),
diff --git a/examples/mesh/manual_networking/README.md b/examples/mesh/manual_networking/README.md
new file mode 100644 (file)
index 0000000..8615dbd
--- /dev/null
@@ -0,0 +1,14 @@
+# Mesh Manual Networking Example
+
+ESP-MESH provides the function of self-organized networking, but if users disable this function on one node, users must designate a parent for this node.
+
+
+This example demonstrates how to scan a list of parent candidates, choose an appropriate parent and set as the parent of this node.
+
+If no parent is found through this scan, enable the self-organized function to let the ESP-MESH handle it by itself.
+
+Run `make menuconfig` to configure the mesh network channel, router SSID, router password and mesh softAP settings.
+
+When the mesh network is established and if you happen to run this example on ESP-WROVER-KIT boards, the RGB light indicator will show you on which layer devices are. The pink reprents root; the yellow reprents layer 2; the red reprents layer 3; the blue reprents layer 4; the green reprents layer 5; the white reprents layer greater than 5.
+
+