Merge branch 'master' into feature/cmake

This commit is contained in:
Angus Gratton 2018-09-06 20:23:04 +08:00 committed by Angus Gratton
commit cff2ef695a
261 changed files with 3487 additions and 85171 deletions

View file

@ -418,12 +418,7 @@ test_idf_monitor:
expire_in: 1 week
script:
- cd ${IDF_PATH}/tools/test_idf_monitor
- source /opt/pyenv/activate
- pyenv global 2.7.15
- ./run_test_idf_monitor.py
- pyenv global 3.4.8
- ./run_test_idf_monitor.py
- pyenv global system
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./run_test_idf_monitor.py
test_idf_size:
<<: *host_test_template
@ -435,12 +430,7 @@ test_idf_size:
expire_in: 1 week
script:
- cd ${IDF_PATH}/tools/test_idf_size
- source /opt/pyenv/activate
- pyenv global 2.7.15
- ./test.sh
- pyenv global 3.4.8
- ./test.sh
- pyenv global system
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test.sh
test_esp_err_to_name_on_host:
<<: *host_test_template
@ -450,15 +440,11 @@ test_esp_err_to_name_on_host:
- components/esp32/esp_err_to_name.c
expire_in: 1 week
script:
- cd tools/
- source /opt/pyenv/activate
- pyenv global 2.7.15
- ./gen_esp_err_to_name.py
- cd ${IDF_PATH}/tools/
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh -p 2.7.15 ./gen_esp_err_to_name.py
- git diff --exit-code -- ../components/esp32/esp_err_to_name.c || (echo 'Differences found. Please run gen_esp_err_to_name.py and commit the changes.'; exit 1)
- pyenv global 3.4.8
- ./gen_esp_err_to_name.py
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh -p 3.4.8 ./gen_esp_err_to_name.py
- git diff --exit-code -- ../components/esp32/esp_err_to_name.c || (echo 'Differences found between running under Python 2 and 3.'; exit 1)
- pyenv global system
push_to_github:
stage: deploy
@ -481,9 +467,7 @@ push_to_github:
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- git remote remove github &>/dev/null || true
- git remote add github git@github.com:espressif/esp-idf.git
# Need separate push commands for tag builds and for branch builds
- "[ -n \"${CI_COMMIT_TAG}\" ] && git push github ${CI_COMMIT_TAG}"
- "[ -z \"${CI_COMMIT_TAG}\" ] && git push github ${CI_COMMIT_SHA}:refs/heads/${CI_COMMIT_REF_NAME}"
- tools/ci/push_to_github.sh
deploy_docs:
stage: host_test
@ -926,7 +910,7 @@ UT_001_25:
tags:
- ESP32_IDF
- UT_T1_1
UT_001_26:
<<: *unit_test_template
tags:
@ -962,7 +946,7 @@ UT_001_31:
tags:
- ESP32_IDF
- UT_T1_1
UT_001_32:
<<: *unit_test_template
tags:
@ -974,7 +958,7 @@ UT_001_33:
tags:
- ESP32_IDF
- UT_T1_1
UT_001_34:
<<: *unit_test_template
tags:
@ -1098,14 +1082,14 @@ UT_004_10:
- ESP32_IDF
- UT_T1_1
- psram
UT_004_11:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
- psram
UT_005_01:
<<: *unit_test_template
tags:
@ -1248,55 +1232,19 @@ IT_001_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
- SSC_T1_4
IT_001_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
- SSC_T1_4
IT_001_03:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
IT_001_04:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
IT_001_05:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
IT_001_06:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
IT_001_07:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
IT_001_08:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
IT_001_09:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
- SSC_T1_4
IT_002_01:
<<: *test_template
@ -1308,85 +1256,79 @@ IT_003_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_03:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_04:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_05:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_06:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_07:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_08:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_09:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_10:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_11:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_12:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_003_13:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
IT_003_14:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- SSC_T2_5
IT_004_01:
<<: *test_template
@ -1398,7 +1340,61 @@ IT_005_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_WEP
- SSC_T1_5
IT_005_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_5
IT_006_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_6
IT_006_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_6
IT_006_03:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_6
IT_006_04:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_6
IT_006_05:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_6
IT_007_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_7
IT_007_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_7
IT_008_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_8
IT_009_01:
<<: *test_template
@ -1418,58 +1414,32 @@ IT_011_01:
- ESP32_IDF
- SSC_T50_1
IT_501_01:
IT_012_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
- stress_test
- SSC_T1_9
IT_501_02:
IT_013_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
- stress_test
- SSC_T2_2
IT_501_03:
IT_013_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_1
- stress_test
- SSC_T2_2
IT_502_01:
IT_014_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- stress_test
- SSC_T2_3
IT_502_02:
IT_015_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T2_1
- stress_test
IT_503_01:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T5_1
- stress_test
IT_503_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T5_1
- stress_test
IT_503_03:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T5_1
- stress_test
- SSC_T2_4

4
.gitmodules vendored
View file

@ -49,3 +49,7 @@
[submodule "components/expat/expat"]
path = components/expat/expat
url = https://github.com/libexpat/libexpat.git
[submodule "components/lwip/lwip"]
path = components/lwip/lwip
url = https://github.com/espressif/esp-lwip.git

View file

@ -429,7 +429,6 @@ static void bta_hf_client_sco_event(UINT8 event)
if (event == BTA_HF_CLIENT_SCO_CI_DATA_E) {
uint16_t pkt_offset = 1 + HCI_SCO_PREAMBLE_SIZE;
uint16_t len_to_send = 0;
uint8_t *p;
while (true)
{
p_buf = osi_malloc(sizeof(BT_HDR) + pkt_offset + BTM_SCO_DATA_SIZE_MAX);
@ -439,13 +438,13 @@ static void bta_hf_client_sco_event(UINT8 event)
}
p_buf->offset = pkt_offset;
p_buf->len = BTM_SCO_DATA_SIZE_MAX;
len_to_send = bta_hf_client_sco_co_out_data(p_buf->data + pkt_offset, BTM_SCO_DATA_SIZE_MAX);
if (len_to_send) {
if (len_to_send == BTM_SCO_DATA_SIZE_MAX) {
// expect to get the exact size of data from upper layer
if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
p = (UINT8 *)(p_buf->data + pkt_offset -1);
*p = len_to_send; // set SCO packet length;
tBTM_STATUS write_stat = BTM_WriteScoData(p_scb->sco_idx, p_buf);
if (write_stat != BTM_SUCCESS && write_stat != BTM_SCO_BAD_LENGTH) {
if (write_stat != BTM_SUCCESS) {
break;
}
} else {

View file

@ -170,16 +170,6 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter
BOOLEAN cod_limited;
BTM_TRACE_API ("BTM_SetDiscoverability\n");
#if (BLE_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
if (controller_get_interface()->supports_ble()) {
if (btm_ble_set_discoverability((UINT16)(inq_mode))
== BTM_SUCCESS) {
btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK);
btm_cb.btm_inq_vars.discoverable_mode |= (inq_mode & BTM_BLE_DISCOVERABLE_MASK);
}
}
inq_mode &= ~BTM_BLE_DISCOVERABLE_MASK;
#endif
/*** Check mode parameter ***/
if (inq_mode > BTM_MAX_DISCOVERABLE) {
@ -601,17 +591,6 @@ tBTM_STATUS BTM_SetConnectability (UINT16 page_mode, UINT16 window, UINT16 inter
BTM_TRACE_API ("BTM_SetConnectability\n");
#if (BLE_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
if (controller_get_interface()->supports_ble()) {
if (btm_ble_set_connectability(page_mode) != BTM_SUCCESS) {
return BTM_NO_RESOURCES;
}
p_inq->connectable_mode &= (~BTM_BLE_CONNECTABLE_MASK);
p_inq->connectable_mode |= (page_mode & BTM_BLE_CONNECTABLE_MASK);
}
page_mode &= ~BTM_BLE_CONNECTABLE_MASK;
#endif
/*** Check mode parameter ***/
if (page_mode != BTM_NON_CONNECTABLE && page_mode != BTM_CONNECTABLE) {
return (BTM_ILLEGAL_VALUE);

View file

@ -431,12 +431,13 @@ tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf)
/* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
and set warning status */
if (p_buf->len > BTM_SCO_DATA_SIZE_MAX) {
BTM_TRACE_WARNING ("BTM SCO hdl %x, bad len %u", p_ccb->hci_handle, p_buf->len);
p_buf->len = BTM_SCO_DATA_SIZE_MAX;
status = BTM_SCO_BAD_LENGTH;
}
UINT8_TO_STREAM (p, (UINT8)p_buf->len);
BTM_TRACE_DEBUG ("BTM SCO hdl %x, len %u", p_ccb->hci_handle, p_buf->len);
p_buf->len += HCI_SCO_PREAMBLE_SIZE;
if (fixed_queue_length(p_ccb->xmit_data_q) < BTM_SCO_XMIT_QUEUE_THRS) {
@ -453,7 +454,7 @@ tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf)
status = BTM_UNKNOWN_ADDR;
}
if (status != BTM_SUCCESS && status != BTM_SCO_BAD_LENGTH) {
if (status != BTM_SUCCESS) {
BTM_TRACE_WARNING ("stat %d", status);
osi_free(p_buf);
}

View file

@ -4,6 +4,9 @@
#if __has_include("soc/soc.h")
#include "soc/soc.h"
#endif
#if __has_include("apps/ping/esp_ping.h")
#include "apps/ping/esp_ping.h"
#endif
#if __has_include("esp32/ulp.h")
#include "esp32/ulp.h"
#endif
@ -25,9 +28,6 @@
#if __has_include("esp_ota_ops.h")
#include "esp_ota_ops.h"
#endif
#if __has_include("esp_ping.h")
#include "esp_ping.h"
#endif
#if __has_include("esp_spi_flash.h")
#include "esp_spi_flash.h"
#endif
@ -399,7 +399,7 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED), /* 20487 0x5007 */
# endif
// components/lwip/apps/ping/esp_ping.h
// components/lwip/include/apps/ping/esp_ping.h
# ifdef ESP_ERR_PING_BASE
ERR_TBL_IT(ESP_ERR_PING_BASE), /* 24576 0x6000 */
# endif

View file

@ -319,6 +319,12 @@ esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
*/
void esp_default_wake_deep_sleep(void);
/**
* @brief Disable logging from the ROM code after deep sleep.
*
* Using LSB of RTC_STORE4.
*/
void esp_deep_sleep_disable_rom_logging(void);
#ifdef __cplusplus
}

View file

@ -55,7 +55,7 @@ extern "C" {
* RTC_CNTL_STORE1_REG RTC_SLOW_CLK calibration value
* RTC_CNTL_STORE2_REG Boot time, low word
* RTC_CNTL_STORE3_REG Boot time, high word
* RTC_CNTL_STORE4_REG External XTAL frequency
* RTC_CNTL_STORE4_REG External XTAL frequency. The frequency must necessarily be even, otherwise there will be a conflict with the low bit, which is used to disable logs in the ROM code.
* RTC_CNTL_STORE5_REG APB bus frequency
* RTC_CNTL_STORE6_REG FAST_RTC_MEMORY_ENTRY
* RTC_CNTL_STORE7_REG FAST_RTC_MEMORY_CRC
@ -71,6 +71,7 @@ extern "C" {
#define RTC_RESET_CAUSE_REG RTC_CNTL_STORE6_REG
#define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG
#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code.
typedef enum {
AWAKE = 0, //<CPU ON

View file

@ -658,3 +658,13 @@ static uint32_t get_power_down_flags()
}
return pd_flags;
}
void esp_deep_sleep_disable_rom_logging(void)
{
/* To disable logging in the ROM, only the least significant bit of the register is used,
* but since this register is also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG),
* you need to write to this register in the same format.
* Namely, the upper 16 bits and lower should be the same.
*/
REG_SET_BIT(RTC_CNTL_STORE4_REG, RTC_DISABLE_ROM_LOG);
}

View file

@ -149,7 +149,7 @@ esp_err_t esp_efuse_mac_get_default(uint8_t* mac)
esp_err_t system_efuse_read_mac(uint8_t *mac) __attribute__((alias("esp_efuse_mac_get_default")));
esp_err_t esp_efuse_read_mac(uint8_t *mac) __attribute__((alias("esp_efuse_mac_get_default")));
esp_err_t esp_derive_mac(uint8_t* local_mac, const uint8_t* universal_mac)
esp_err_t esp_derive_local_mac(uint8_t* local_mac, const uint8_t* universal_mac)
{
uint8_t idx;
@ -203,7 +203,7 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
mac[5] += 1;
}
else if (UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR) {
esp_derive_mac(mac, efuse_mac);
esp_derive_local_mac(mac, efuse_mac);
}
break;
case ESP_MAC_BT:
@ -222,7 +222,7 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
}
else if (UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR) {
efuse_mac[5] += 1;
esp_derive_mac(mac, efuse_mac);
esp_derive_local_mac(mac, efuse_mac);
}
break;
default:

View file

@ -0,0 +1,182 @@
.MESH_INIT_COND: &MESH_INIT_COND
test script: InitCondMesh
restore post cmd set:
- ''
- - 'MSSC SSC[1-<node_num>] mesh -F -o 4 -a 1'
- ['P SSC[1-<node_num>] C +MESHFLAG:OK']
- - 'MSSC SSC[1-<node_num>] mesh -F -o 5 -a 1'
- ['P SSC[1-<node_num>] C +MESHFLAG:OK']
- - 'MSSC SSC[1-<node_num>] mesh -Q -o 1'
- ['P SSC[1-<node_num>] C MESH_NETWORK']
- - 'MSSC SSC[1-<node_num>] mesh -Q -o 3'
- ['P SSC[1-<node_num>] C +MESH_CONFIG:ALL']
- - 'MSSC SSC[1-<node_num>] ram'
- ['P SSC[1-<node_num>] C +FREEHEAP:']
.mesh_get_device_mac: &mesh_get_device_mac
LIST_MERGE:
- - 'MSSC SSC[1-<node_num>] mac'
- ['R SSC[1-<node_num>] A <device_mac>:\+STAMAC:(.+)\r\n']
.mesh_check_get_tree: &mesh_check_get_tree
LIST_MERGE:
- - 'MSSC SSC[1-<node_num>] mac'
- ['P SSC[1-<node_num>] A <device_mac>:\+STAMAC:(.+)\r\n']
- - 'MSSC SSC[1-<node_num>] mesh -Q -o 2'
- ['P SSC[1-<node_num>] T <node_num>']
- - 'MESHTREE'
- ['P PC_COM RE "MESHTREE:%%s%20nodes"%%(<node_num>)']
.mesh_check_tree_stable: &mesh_check_tree_stable
LIST_MERGE:
- - 'DELAY 10'
- ['']
- - 'SSC MNODE(0) mesh -Q -o 1 -t 10'
- ['R MNODE(0) C MESH_STABLE_CHECK:PASS']
.reboot_all: &reboot_all
LIST_MERGE:
- - 'MSSC SSC[1-<node_num>] reboot'
- ['P SSC[1-<node_num>] C !!!ready!!!']
.force_reboot: &force_reboot
LIST_MERGE:
- - 'FPOWERON SSC[1-<node_num>]'
- ['']
- - 'DELAY 1'
- ['']
- - 'MSSC SSC[1-<node_num>] restore'
- ['P SSC[1-<node_num>] C !!!ready!!!']
.all_nodes_mesh_config: &all_nodes_mesh_config
LIST_MERGE:
- - 'MSSC SSC[1-<node_num>] mesh -I'
- ['P SSC[1-<node_num>] C +MESH:INITED']
- - 'MSSC SSC[1-<node_num>] mesh -A -o 12 -t <duration_ms> -c <cnx_rssi> -l <select_rssi> -f <switch_rssi> -b <backoff_rssi>'
- ['P SSC[1-<node_num>] C +MESH_SET_PARENT_SWITCH:OK']
- - 'MSSC SSC[1-<node_num>] mesh -A -o 14 -t <threshold_high> -c <threshold_medium> -l <threshold_low>'
- ['P SSC[1-<node_num>] C +MESH_RSSI_THRESHOLD:OK']
- - 'MSSC SSC[1-<node_num>] mesh -A -o 9 -t <auth_mode> -s <map_password>'
- ['P SSC[1-<node_num>] C +MESH_SET_AP_AUTH_MODE:OK']
- - 'MSSC SSC[1-<node_num>] mesh -P -g <mesh_id> -s <ap_ssid> -p <ap_password> -n <ap_channel> -m <max_connect> -y <max_layer>'
- ['P SSC[1-<node_num>] C +MESH:CONFIG,OK']
.root_do_connect: &root_do_connect
LIST_MERGE:
- - 'SOC SOC1 LISTEN <test_tcp_port1> <pc_ip>'
- ['R SOC_COM L OK']
- - 'SSC MNODE(0) mesh -S -o 0 -i <pc_ip> -t <test_tcp_port1>'
- ['P MNODE(0) C +CONNECT,OK']
- ['P SOC1 C +ACCEPT']
- - 'SOC SOC1 MACCEPT GSOC1'
- ['R SOC_COM L OK']
initial condition:
- tag: ENABLED_1
<<: *MESH_INIT_COND
initial condition detail: if mesh tree not exist, start one node first, then start others, after mesh network
established, root connect server
check cmd set:
- ''
- *mesh_check_get_tree
- *mesh_check_tree_stable
- *root_do_connect
restore cmd set:
- ''
- *reboot_all
- *all_nodes_mesh_config
- - SSC SSC1 mesh -T
- - P SSC1 C +MESH:START,OK
- - DELAY 10
- - P SSC1 C MESH_EVENT_CONNECTED
- - SSC SSC[2-<node_num>] mesh -T
- - P SSC[2-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- *mesh_check_get_tree
- *mesh_check_tree_stable
- *root_do_connect
force restore cmd set:
- ''
- *force_reboot
- *all_nodes_mesh_config
- - SSC SSC1 mesh -T
- - P SSC1 C +MESH:START,OK
- - DELAY 10
- - P SSC1 C MESH_EVENT_CONNECTED
- - SSC SSC[2-<node_num>] mesh -T
- - P SSC[2-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- *mesh_check_get_tree
- *mesh_check_tree_stable
- *root_do_connect
- tag: ENABLED_2
<<: *MESH_INIT_COND
initial condition detail: if mesh tree not exist, start all nodes together
check cmd set:
- ''
- *mesh_check_get_tree
- *mesh_check_tree_stable
restore cmd set:
- ''
- *reboot_all
- *all_nodes_mesh_config
- - MSSC SSC[1-<node_num>] mesh -T
- - P SSC[1-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- *mesh_check_get_tree
- *mesh_check_tree_stable
force restore cmd set:
- ''
- *force_reboot
- *all_nodes_mesh_config
- - MSSC SSC[1-<node_num>] mesh -T
- - P SSC[1-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- *mesh_check_get_tree
- *mesh_check_tree_stable
- tag: ENABLED_3
<<: *MESH_INIT_COND
initial condition detail: all mesh nodes configed but not started
check cmd set:
- ''
- - ASSERT
- - ''
restore cmd set:
- ''
- *reboot_all
- *all_nodes_mesh_config
- *mesh_get_device_mac
force restore cmd set:
- ''
- *force_reboot
- *all_nodes_mesh_config
- *mesh_get_device_mac
- tag: DISABLED_1
<<: *MESH_INIT_COND
initial condition detail: all mesh node in softap+sta mode, disable all mesh node
restore post cmd set:
- ''
check cmd set:
- ''
- - ASSERT
- - ''
restore cmd set:
- ''
- *reboot_all
- - MSSC SSC[1-<node_num>] op -S -o 3
- - P SSC[1-<node_num>] C +MODE:OK
- - MSSC SSC[1-<node_num>] sta -D
- - P SSC[1-<node_num>] C +QAP:OK
- *mesh_get_device_mac
force restore cmd set:
- ''
- *force_reboot
- - MSSC SSC[1-<node_num>] op -S -o 3
- - P SSC[1-<node_num>] C +MODE:OK
- - MSSC SSC[1-<node_num>] sta -D
- - P SSC[1-<node_num>] C +QAP:OK
- *mesh_get_device_mac

View file

@ -7,16 +7,12 @@
- - SSC SSC1 ram
- - 'R SSC1 C +FREEHEAP:'
.MESH_INIT_COND: &MESH_INIT_COND
test script: InitCondBase
restore post cmd set:
- ''
- - SSC SSC[1-<node_num>] mesh -Q -o 1
- - R SSC[1-<node_num>] C MESH_NETWORK
- - SSC SSC[1-<node_num>] mesh -Q -o 3
- - R SSC[1-<node_num>] C +MESH_CONFIG:ALL
- - SSC SSC[1-<node_num>] ram
- - R SSC[1-<node_num>] A <heap_size>:(\d+)
.dut1_start_wifi: &dut1_start_wifi
LIST_MERGE:
- - SSC SSC1 op -W -a init
- - R SSC1 C +MODE
- - SSC SSC1 op -W -a start
- - R SSC1 C +MODE
initial condition:
- tag: APM1
@ -25,6 +21,7 @@ initial condition:
APSTA1
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:2
- - SSC SSC1 ap -Q
@ -61,6 +58,7 @@ initial condition:
condition APSTA2
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:2
- - SSC SSC1 ap -Q
@ -105,6 +103,7 @@ initial condition:
APSTA1
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:2
- - SSC SSC1 ap -Q
@ -141,6 +140,7 @@ initial condition:
APSTA2
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:2
- - SSC SSC1 ap -Q
@ -182,6 +182,7 @@ initial condition:
- <<: *SSC_INIT_COND
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 upgrade -Q -t 1
- - R SSC1 C BIN_ID,0
- - SSC SSC1 upgrade -Q -t 2 -b 0
@ -225,6 +226,7 @@ initial condition:
initial condition detail: testing ap on sta + ap mode (autogen by APM1)
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:3
- - SSC SSC1 ap -Q
@ -260,6 +262,7 @@ initial condition:
initial condition detail: testing ap on sta + ap mode, PC join AP (autogen by APM2)
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:3
- - SSC SSC1 ap -Q
@ -978,7 +981,7 @@ initial condition:
- tag: BLE_INIT2
<<: *SSC_INIT_COND
initial condition detail: 2 DUT which BLE is enabled, no active connection, DUT2
start adv
load service 0xA0 and start adv
check cmd set:
- ''
- - SSC SSC[1-2] bt -Q
@ -1018,6 +1021,49 @@ initial condition:
- - R SSC2 C +BLEADV:SetAdv,OK
- - SSC SSC2 bleadv -D -z start
- - R SSC2 C +BLEADV:OK
- - SSC SSC1 ram
- - R SSC1 A <heap_size>:(\d+)
- tag: BLE_INIT3
<<: *SSC_INIT_COND
initial condition detail: 2 DUT which BLE is enabled, no active connection, DUT2
load service 0xA2 and start adv
check cmd set:
- ''
- - SSC SSC[1-2] bt -Q
- - R SSC[1-2] C +BT:status,ENABLE
restore cmd set:
- ''
- - SSC SSC[1-2] bt -D -z init
- - 'R SSC[1-2] C +BT:'
- - SSC SSC[1-2] bt -D -z enable
- - 'R SSC[1-2] C +BT:'
force restore cmd set:
- ''
- - SSC SSC[1-2] reboot
- - R SSC[1-2] C !!!ready!!!
- - SSC SSC[1-2] bt -D -z init
- - 'R SSC[1-2] C +BT:'
- - SSC SSC[1-2] bt -D -z enable
- - 'R SSC[1-2] C +BT:'
restore post cmd set:
- ''
- - SSC SSC[1-2] ble -R
- - 'R SSC[1-2] C +BLE:'
- - SSC SSC[1-2] bleconn -D -z all
- - 'R SSC[1-2] C +BLECONN:'
- - SSC SSC[1-2] gatts -S -z delete
- - 'R SSC[1-2] C +GATTS:'
- - SSC SSC[1-2] gattc -U -z all
- - R SSC[1-2] C +GATTC:OK
- - SSC SSC2 gatts -S -z load -p 0xA2
- - R SSC2 C +GATTS:StartService,OK,A002
- - SSC SSC[1-2] bleadv -D -z stop
- - R SSC[1-2] C +BLEADV:OK
- - SSC SSC2 bleadv -L -c 0 -t 3
- - R SSC2 C +BLEADV:SetAdv,OK
- - SSC SSC2 bleadv -D -z start
- - R SSC2 C +BLEADV:OK
- - SSC SSC1 ram
- - R SSC1 A <heap_size>:(\d+)
- tag: BLE_INIT5
@ -1065,7 +1111,7 @@ initial condition:
- tag: BLE_INIT_SMP
<<: *SSC_INIT_COND
initial condition detail: 2 DUT which BLE is enabled, no active connection, DUT2
create GATT service 0xA000, DUT2 start adv, SMP enabled on both DUT and DUT1 load
create GATT service 0xA002, DUT2 start adv, SMP enabled on both DUT and DUT1 load
default initiator param, DUT2 load default responder param
check cmd set:
- ''
@ -1091,8 +1137,8 @@ initial condition:
- - R SSC[1-2] C +GATTC:OK
- - SSC SSC[1-2] bleadv -D -z stop
- - R SSC[1-2] C +BLEADV:OK
- - SSC SSC2 gatts -S -z load -p 0xA0
- - R SSC2 C +GATTS:StartService,OK,A000
- - SSC SSC2 gatts -S -z load -p 0xA2
- - R SSC2 C +GATTS:StartService,OK,A002
- - SSC SSC2 bleadv -L -c 0 -t 3
- - R SSC2 C +BLEADV:SetAdv,OK
- - SSC SSC2 bleadv -D -z start
@ -1120,8 +1166,8 @@ initial condition:
- - R SSC[1-2] C +GATTC:OK
- - SSC SSC[1-2] bleadv -D -z stop
- - R SSC[1-2] C +BLEADV:OK
- - SSC SSC2 gatts -S -z load -p 0xA0
- - R SSC2 C +GATTS:StartService,OK,A000
- - SSC SSC2 gatts -S -z load -p 0xA2
- - R SSC2 C +GATTS:StartService,OK,A002
- - SSC SSC2 bleadv -L -c 0 -t 3
- - R SSC2 C +BLEADV:SetAdv,OK
- - SSC SSC2 bleadv -D -z start
@ -1171,6 +1217,8 @@ initial condition:
- - R SSC[1-5] C +BLESMP:OK
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- - R SSC1 C +GATTC:OK
- - SSC SSC1 ram
- - R SSC1 A <heap_size>:(\d+)
restore post cmd set:
- ''
- - SSC SSC[1-5] ble -R
@ -1205,6 +1253,7 @@ initial condition:
initial condition detail: one target in AP mode and espnow is de-initialized
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:2
- - SSC SSC1 mac -Q -o 2
@ -1239,6 +1288,7 @@ initial condition:
with self role slave
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC[1-<dev_num>] op -Q
- - R SSC[1-<dev_num>] C +CURMODE:2
- - SSC SSC[1-<dev_num>] mac -Q -o 3
@ -1422,6 +1472,7 @@ initial condition:
initial condition detail: testing sta on sta + ap mode, quit AP (autogen by STAM1)
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:3
- - SSC SSC1 sta -D
@ -1458,6 +1509,7 @@ initial condition:
by STAM2)
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:3
- - SSC SSC1 sta -Q
@ -1494,6 +1546,7 @@ initial condition:
condition STAAP1
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:1
- - SSC SSC1 sta -D
@ -1530,6 +1583,7 @@ initial condition:
condition STAAP2
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:1
- - SSC SSC1 sta -Q
@ -1566,6 +1620,7 @@ initial condition:
condition STAAP1
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:1
- - SSC SSC1 sta -D
@ -1602,6 +1657,7 @@ initial condition:
initial condition STAAP2
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:1
- - SSC SSC1 sta -Q
@ -1704,6 +1760,7 @@ initial condition:
T2_2
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:2
- - SSC SSC2 op -Q
@ -1766,6 +1823,7 @@ initial condition:
with initial condition T2_2
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:2
- - SSC SSC2 op -Q
@ -1827,6 +1885,7 @@ initial condition:
initial condition detail: target 1 as AP+STA, target 2 as AP+STA (autogen)
check cmd set:
- ''
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:3
- - SSC SSC2 op -Q
@ -2049,209 +2108,44 @@ initial condition:
- - R SSC[1-2] C +BLEADV:OK
- - SSC SSC1 ram
- - R SSC1 A <heap_size>:(\d+)
- tag: ENABLED_1
<<: *MESH_INIT_COND
initial condition detail: if mesh tree not exist, start one node first, then start others, after mesh network
established, root connect server
- tag: T3_1
<<: *SSC_INIT_COND
initial condition detail: target 1 as SoftAP + STA, target 2 as SoftAP, target 3 as STA
with initial condition T2_2
check cmd set:
- ''
- - SSC SSC[1-<node_num>] mesh -Q -o 2
- - R SSC[1-<node_num>] T <node_num>
- - MESHTREE
- - R PC_COM RE "MESHTREE:%%s%20nodes"%%(<node_num>)
- - SOC SOC1 LISTEN <test_tcp_port1> <pc_ip>
- - R SOC_COM L OK
- - SSC MNODE(0) mesh -S -o 0 -i <pc_ip> -t <test_tcp_port1>
- - ''
- - SOC SOC1 MACCEPT GSOC1
- - P MNODE(0) C +CONNECT,OK
- R SOC_COM L OK
- - SSC SSC[1-<node_num>] mesh -F -o 4 -a 1
- - P SSC[1-<node_num>] C +MESHFLAG:OK
- - SSC SSC[1-<node_num>] mesh -F -o 5 -a 1
- - P SSC[1-<node_num>] C +MESHFLAG:OK
- *dut1_start_wifi
- - SSC SSC1 op -Q
- - R SSC1 C +CURMODE:3
- - SSC SSC2 op -Q
- - R SSC2 C +CURMODE:2
- - SSC SSC3 op -Q
- - R SSC3 C +CURMODE:1
- - SSC SSC3 sta -D
- - 'R SSC3 C +QAP:'
restore cmd set:
- ''
- - SSC SSC[1-<node_num>] reboot
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] mesh -I
- - P SSC[1-<node_num>] C +MESH:INITED
- - SSC SSC[1-<node_num>] mesh -A -o 12 -t <duration_ms> -c <cnx_rssi> -l <select_rssi> -f <switch_rssi> -b <backoff_rssi>
- - P SSC[1-<node_num>] C +MESH_SET_PARENT_SWITCH:OK
- - SSC SSC[1-<node_num>] mesh -A -o 9 -t <auth_mode> -s <map_password>
- - P SSC[1-<node_num>] C +MESH_SET_AP_AUTH_MODE:OK C +MESH_SET_AP_AUTH_PWD:OK
- - SSC SSC[1-<node_num>] mesh -P -g <mesh_id> -s <ap_ssid> -p <ap_password> -n
<ap_channel> -m <max_connect> -y <max_layer>
- - P SSC[1-<node_num>] C +MESH:CONFIG,OK
- - SSC SSC1 mesh -T
- - P SSC1 C +MESH:START,OK
- - DELAY 10
- - ''
- - SSC SSC[2-<node_num>] mesh -T
- - P SSC[2-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- - SSC SSC[1-<node_num>] mesh -Q -o 2
- - R SSC[1-<node_num>] T <node_num>
- - MESHTREE
- - R PC_COM RE "MESHTREE:%%s%20nodes"%%(<node_num>)
- - SSC MNODE(0) mesh -Q -o 1 -t <delay_time>
- - R MNODE(0) C NETWORK_TIME:PASS
- - SOC SOC1 LISTEN <test_tcp_port1> <pc_ip>
- - R SOC_COM L OK
- - SSC MNODE(0) mesh -S -o 0 -i <pc_ip> -t <test_tcp_port1>
- - ''
- - SOC SOC1 MACCEPT GSOC1
- - P MNODE(0) C +CONNECT,OK
- R SOC_COM L OK
- - SSC SSC[1-<node_num>] mesh -F -o 4 -a 1
- - P SSC[1-<node_num>] C +MESHFLAG:OK
- - SSC SSC[1-<node_num>] mesh -F -o 5 -a 1
- - P SSC[1-<node_num>] C +MESHFLAG:OK
- - SSC SSC1 op -S -o 3
- - R SSC1 C +MODE:OK
- - SSC SSC2 op -S -o 2
- - R SSC2 C +MODE:OK
- - SSC SSC3 op -S -o 1
- - R SSC3 C +MODE:OK
- - SSC SSC3 sta -D
- - 'R SSC3 C +QAP:'
force restore cmd set:
- ''
- - SSC SSC[1-<node_num>] restore
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] mesh -I
- - P SSC[1-<node_num>] C +MESH:INITED
- - SSC SSC[1-<node_num>] mesh -A -o 12 -t <duration_ms> -c <cnx_rssi> -l <select_rssi> -f <switch_rssi> -b <backoff_rssi>
- - P SSC[1-<node_num>] C +MESH_SET_PARENT_SWITCH:OK
- - SSC SSC[1-<node_num>] mesh -A -o 9 -t <auth_mode> -s <map_password>
- - P SSC[1-<node_num>] C +MESH_SET_AP_AUTH_MODE:OK C +MESH_SET_AP_AUTH_PWD:OK
- - SSC SSC[1-<node_num>] mesh -P -g <mesh_id> -s <ap_ssid> -p <ap_password> -n
<ap_channel> -m <max_connect> -y <max_layer>
- - P SSC[1-<node_num>] C +MESH:CONFIG,OK
- - SSC SSC1 mesh -T
- - P SSC1 C +MESH:START,OK
- - DELAY 10
- - ''
- - SSC SSC[2-<node_num>] mesh -T
- - P SSC[2-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- - SSC SSC[1-<node_num>] mesh -Q -o 2
- - R SSC[1-<node_num>] T <node_num>
- - MESHTREE
- - R PC_COM RE "MESHTREE:%%s%20nodes"%%(<node_num>)
- - SSC MNODE(0) mesh -Q -o 1 -t <delay_time>
- - R MNODE(0) C NETWORK_TIME:PASS
- - SOC SOC1 LISTEN <test_tcp_port1> <pc_ip>
- - R SOC_COM L OK
- - SSC MNODE(0) mesh -S -o 0 -i <pc_ip> -t <test_tcp_port1>
- - ''
- - SOC SOC1 MACCEPT GSOC1
- - P MNODE(0) C +CONNECT,OK
- R SOC_COM L OK
- - SSC SSC[1-<node_num>] mesh -F -o 4 -a 1
- - P SSC[1-<node_num>] C +MESHFLAG:OK
- - SSC SSC[1-<node_num>] mesh -F -o 5 -a 1
- - P SSC[1-<node_num>] C +MESHFLAG:OK
- tag: ENABLED_2
<<: *MESH_INIT_COND
initial condition detail: if mesh tree not exist, start all nodes together
check cmd set:
- ''
- - SSC SSC[1-<node_num>] mesh -Q -o 2
- - R SSC[1-<node_num>] T <node_num>
- - MESHTREE
- - R PC_COM RE "MESHTREE:%%s%20nodes"%%(<node_num>)
restore cmd set:
- ''
- - SSC SSC[1-<node_num>] reboot
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] mesh -I
- - P SSC[1-<node_num>] C +MESH:INITED
- - SSC SSC[1-<node_num>] mesh -A -o 12 -t <duration_ms> -c <cnx_rssi> -l <select_rssi> -f <switch_rssi> -b <backoff_rssi>
- - P SSC[1-<node_num>] C +MESH_SET_PARENT_SWITCH:OK
- - SSC SSC[1-<node_num>] mesh -A -o 9 -t <auth_mode> -s <map_password>
- - P SSC[1-<node_num>] C +MESH_SET_AP_AUTH_MODE:OK C +MESH_SET_AP_AUTH_PWD:OK
- - SSC SSC[1-<node_num>] mesh -P -g <mesh_id> -s <ap_ssid> -p <ap_password> -n
<ap_channel> -m <max_connect> -y <max_layer>
- - P SSC[1-<node_num>] C +MESH:CONFIG,OK
- - SSC SSC[1-<node_num>] mesh -T
- - P SSC[1-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- - SSC SSC[1-<node_num>] mesh -Q -o 2
- - R SSC[1-<node_num>] T <node_num>
- - MESHTREE
- - R PC_COM RE "MESHTREE:%%s%20nodes"%%(<node_num>)
- - SSC MNODE(0) mesh -Q -o 1 -t <delay_time>
- - R MNODE(0) C NETWORK_TIME:PASS
force restore cmd set:
- ''
- - SSC SSC[1-<node_num>] restore
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] mesh -I
- - P SSC[1-<node_num>] C +MESH:INITED
- - SSC SSC[1-<node_num>] mesh -A -o 12 -t <duration_ms> -c <cnx_rssi> -l <select_rssi> -f <switch_rssi> -b <backoff_rssi>
- - P SSC[1-<node_num>] C +MESH_SET_PARENT_SWITCH:OK
- - SSC SSC[1-<node_num>] mesh -A -o 9 -t <auth_mode> -s <map_password>
- - P SSC[1-<node_num>] C +MESH_SET_AP_AUTH_MODE:OK C +MESH_SET_AP_AUTH_PWD:OK
- - SSC SSC[1-<node_num>] mesh -P -g <mesh_id> -s <ap_ssid> -p <ap_password> -n
<ap_channel> -m <max_connect> -y <max_layer>
- - P SSC[1-<node_num>] C +MESH:CONFIG,OK
- - SSC SSC[1-<node_num>] mesh -T
- - P SSC[1-<node_num>] C +MESH:START,OK
- - DELAY <delay_time>
- - ''
- - SSC SSC[1-<node_num>] mesh -Q -o 2
- - R SSC[1-<node_num>] T <node_num>
- - MESHTREE
- - R PC_COM RE "MESHTREE:%%s%20nodes"%%(<node_num>)
- - SSC MNODE(0) mesh -Q -o 1 -t <delay_time>
- - R MNODE(0) C NETWORK_TIME:PASS
- tag: ENABLED_3
<<: *MESH_INIT_COND
initial condition detail: all mesh nodes in softap+sta mode, mesh configed but not started
check cmd set:
- ''
restore cmd set:
- ''
- - SSC SSC[1-<node_num>] reboot
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] mesh -I
- - P SSC[1-<node_num>] C +MESH:INITED
- - SSC SSC[1-<node_num>] mesh -A -o 12 -t <duration_ms> -c <cnx_rssi> -l <select_rssi> -f <switch_rssi> -b <backoff_rssi>
- - P SSC[1-<node_num>] C +MESH_SET_PARENT_SWITCH:OK
- - SSC SSC[1-<node_num>] mesh -A -o 9 -t <auth_mode> -s <map_password>
- - P SSC[1-<node_num>] C +MESH_SET_AP_AUTH_MODE:OK C +MESH_SET_AP_AUTH_PWD:OK
- - SSC SSC[1-<node_num>] mesh -P -g <mesh_id> -s <ap_ssid> -p <ap_password> -n
<ap_channel> -m <max_connect> -y <max_layer>
- - P SSC[1-<node_num>] C +MESH:CONFIG,OK
force restore cmd set:
- ''
- - SSC SSC[1-<node_num>] restore
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] mesh -I
- - P SSC[1-<node_num>] C +MESH:INITED
- - SSC SSC[1-<node_num>] mesh -A -o 12 -t <duration_ms> -c <cnx_rssi> -l <select_rssi> -f <switch_rssi> -b <backoff_rssi>
- - P SSC[1-<node_num>] C +MESH_SET_PARENT_SWITCH:OK
- - SSC SSC[1-<node_num>] mesh -A -o 9 -t <auth_mode> -s <map_password>
- - P SSC[1-<node_num>] C +MESH_SET_AP_AUTH_MODE:OK C +MESH_SET_AP_AUTH_PWD:OK
- - SSC SSC[1-<node_num>] mesh -P -g <mesh_id> -s <ap_ssid> -p <ap_password> -n
<ap_channel> -m <max_connect> -y <max_layer>
- - P SSC[1-<node_num>] C +MESH:CONFIG,OK
- tag: DISABLED_1
<<: *MESH_INIT_COND
initial condition detail: all mesh node in softap+sta mode, disable all mesh node
check cmd set:
- ''
- - ASSERT
- - ''
restore cmd set:
- ''
- - SSC SSC[1-<node_num>] reboot
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] op -Q
- - P SSC[1-<node_num>] C +CURMODE:3
- - SSC SSC[1-<node_num>] sta -D
- - P SSC[1-<node_num>] C +QAP:OK
force restore cmd set:
- ''
- - SSC SSC[1-<node_num>] restore
- - P SSC[1-<node_num>] C !!!ready!!!
- - SSC SSC[1-<node_num>] op -S -o 3
- - P SSC[1-<node_num>] C +MODE:OK
- - SSC SSC[1-<node_num>] sta -D
- - P SSC[1-<node_num>] C +QAP:OK
- - SSC SSC1 reboot
- - R SSC1 C !!!ready!!!
- - SSC SSC2 reboot
- - R SSC2 C !!!ready!!!
- - SSC SSC3 reboot
- - R SSC3 C !!!ready!!!
- - SSC SSC1 op -S -o 3
- - R SSC1 C +MODE:OK
- - SSC SSC2 op -S -o 2
- - R SSC2 C +MODE:OK
- - SSC SSC3 op -S -o 1
- - R SSC3 C +MODE:OK
- - SSC SSC3 sta -D
- - 'R SSC3 C +QAP:'

View file

@ -15,6 +15,8 @@ WIFI_CONN_1101
# Wifi scan issue
WIFI_SCAN_0303
WIFI_SCAN_0303_01
WIFI_CONN_0302
WIFI_CONN_0302_01
WIFI_CONN_0101
WIFI_CONN_0101_01
WIFI_CONN_0102
@ -56,10 +58,7 @@ BTSTK_SMP_05002
BTSTK_SMP_05003
BTSTK_SMP_06004
# GAP
BTSTK_GAP_03005
# GAP multi connect
# multi connect
BTSTK_GAP_10001
BTSTK_GAP_10002
BTSTK_GAP_10003
@ -83,4 +82,8 @@ BTSTK_GATT_33002
BTSTK_GATT_33003
BTSTK_GATT_34001
BTSTK_GATT_34002
BTSTK_GATT_34003
BTSTK_GATT_34003
# GATT read multiple
BTSTK_GATT_27002
BTSTK_GATT_27003

View file

@ -5,7 +5,7 @@
category: Function
test point 1: basic function
initial condition: BLE_INIT2
test environment: SSC_T2_1
test environment: SSC_T2_5
execution time: 0
module: BT Stack
sub module: GAP
@ -350,6 +350,53 @@ test cases:
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ManufacturerSpecificData="0x12345678")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ManufacturerSpecificData="0x12345678")'
- ID: BTSTK_GAP_02006
<<: *GAP_CASE
test point 2: BLE GAP config advertising data
summary: ble set advertising data / scan response manufacturer length not equal to real lenght
steps: |
1. DUT1 stop advertise and set short device name
2. DUT1 set manufacturer 0x12345678 and length 3 for adv data and scan response
3. DUT1 start advertising
4. PC do active scan and capture advertising report
5. DUT1 stop advertise and set short device name
6. DUT1 set manufacturer 0x12345678 and length 10 for adv data and scan response
7. DUT1 start advertising
8. PC do active scan and capture advertising report
expected result: |
1. succeed
2. succeed
3. succeed
4. get manufacturer data 0x12345678 in ADV_IND and SCAN_RSP
5. succeed
6. succeed
7. succeed
8. get manufacturer data 0x12345678 in ADV_IND and SCAN_RSP
initial condition: BLE_INIT1
test environment: SSC_T1_3
version: v2 (2016-03-01)
cmd set:
- ""
- *dut1_stop_adv
- *set_default_ble_name
- - "SSC SSC1 bleadv -L -c 0 -m 0x12345678 -t 3 -l 3"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- *open_capture_nic
- - "HCITOOL 2 -i <hci_nic> lescan"
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ManufacturerSpecificData="0x12345678")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ManufacturerSpecificData="0x12345678")'
- *dut1_stop_adv
- *set_default_ble_name
- - "SSC SSC1 bleadv -L -c 0 -m 0x12345678 -t 3 -l 10"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- *open_capture_nic
- - "HCITOOL 2 -i <hci_nic> lescan"
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ManufacturerSpecificData="0x12345678")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ManufacturerSpecificData="0x12345678")'
- ID: BTSTK_GAP_02007
<<: *GAP_CASE
test point 2: BLE GAP config advertising data
summary: ble set advertising data / scan response service data
@ -378,7 +425,54 @@ test cases:
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ServiceData16BitUUID="1234123456")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ServiceData16BitUUID="1234123456")'
- ID: BTSTK_GAP_02007
- ID: BTSTK_GAP_02008
<<: *GAP_CASE
test point 2: BLE GAP config advertising data
summary: ble set advertising data / scan response service data and set length not equal to real length
steps: |
1. DUT1 stop advertise
2. DUT1 set advertising data and scan response service data 0x1234123456 and service data length 3
3. DUT1 start advertising
4. PC do active scan and capture advertising report
5. DUT1 stop advertise
6. DUT1 set advertising data and scan response service data 0x1234123456 and service data length 10
7. DUT1 start advertising
8. PC do active scan and capture advertising report
expected result: |
1. succeed
2. succeed
3. succeed
4. get ServiceData16BitUUID 0x1234123456 in ADV_IND and SCAN_RSP
5. succeed
6. succeed
7. succeed
8. get ServiceData16BitUUID 0x1234123456 in ADV_IND and SCAN_RSP
initial condition: BLE_INIT1
test environment: SSC_T1_3
version: v2 (2016-03-01)
cmd set:
- ""
- *dut1_stop_adv
- *set_default_ble_name
- - "SSC SSC1 bleadv -L -c 0 -n 0 -d 0x1234123456 -t 3 -l 3"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- *open_capture_nic
- - "HCITOOL 2 -i <hci_nic> lescan"
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ServiceData16BitUUID="1234123456")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ServiceData16BitUUID="1234123456")'
- *dut1_stop_adv
- *set_default_ble_name
- - "SSC SSC1 bleadv -L -c 0 -n 0 -d 0x1234123456 -t 3 -l 10"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- *open_capture_nic
- - "HCITOOL 2 -i <hci_nic> lescan"
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ServiceData16BitUUID="1234123456")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.ServiceData16BitUUID="1234123456")'
- ID: BTSTK_GAP_02009
<<: *GAP_CASE
test point 2: BLE GAP config advertising data
summary: ble set advertising data / scan response service uuid list
@ -407,6 +501,53 @@ test cases:
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.Complete16BitServiceUUID="ABCD")(HCIEvent.data_0.Complete32BitServiceUUID="ABCDDCBA")(HCIEvent.data_0.Complete128BitServiceUUID="12349B5F8000008000100000ABCD0000")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.Complete16BitServiceUUID="ABCD")(HCIEvent.data_0.Complete32BitServiceUUID="ABCDDCBA")(HCIEvent.data_0.Complete128BitServiceUUID="12349B5F8000008000100000ABCD0000")'
- ID: BTSTK_GAP_02010
<<: *GAP_CASE
test point 2: BLE GAP config advertising data
summary: ble set advertising data / scan response service uuid list and uuid length not equal to real length
steps: |
1. DUT1 stop advertise
2. DUT1 set advertising data and scan response not include name, service uuid list 0xABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 and service uuid len 32
3. DUT1 start advertising
4. PC do active scan and capture advertising report
5. DUT1 stop advertise
6. DUT1 set advertising data and scan response not include name, service uuid list 0xABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 and service uuid len 64
7. DUT1 start advertising
8. PC do active scan and capture advertising report
expected result: |
1. succeed
2. succeed
3. succeed
4. get Complete16BitServiceUUID 0xABCD Complete32BitServiceUUID 0xABCDDCBA
and Complete128BitServiceUUID 0x12349B5F8000008000100000ABCD0000 in ADV_IND and SCAN_RSP
5. succeed
6. succeed
7. succeed
8. get Complete16BitServiceUUID 0xABCD Complete32BitServiceUUID 0xABCDDCBA
and Complete128BitServiceUUID 0x12349B5F8000008000100000ABCD0000 in ADV_IND and SCAN_RSP
initial condition: BLE_INIT1
test environment: SSC_T1_3
version: v2 (2016-03-01)
cmd set:
- ""
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -n 0 -x 0 -i 0x00-0x00 -s ABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 -t 3 -l 32"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- *open_capture_nic
- - "HCITOOL 2 -i <hci_nic> lescan"
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.Complete16BitServiceUUID="ABCD")(HCIEvent.data_0.Complete32BitServiceUUID="ABCDDCBA")(HCIEvent.data_0.Complete128BitServiceUUID="12349B5F8000008000100000ABCD0000")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.Complete16BitServiceUUID="ABCD")(HCIEvent.data_0.Complete32BitServiceUUID="ABCDDCBA")(HCIEvent.data_0.Complete128BitServiceUUID="12349B5F8000008000100000ABCD0000")'
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -n 0 -x 0 -i 0x00-0x00 -s ABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 -t 3 -l 64"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- *open_capture_nic
- - "HCITOOL 2 -i <hci_nic> lescan"
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="ADV_IND")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.Complete16BitServiceUUID="ABCD")(HCIEvent.data_0.Complete32BitServiceUUID="ABCDDCBA")(HCIEvent.data_0.Complete128BitServiceUUID="12349B5F8000008000100000ABCD0000")'
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="SCAN_RSP")(HCIEvent.address_0=<dut1_bt_mac>)(HCIEvent.data_0.Complete16BitServiceUUID="ABCD")(HCIEvent.data_0.Complete32BitServiceUUID="ABCDDCBA")(HCIEvent.data_0.Complete128BitServiceUUID="12349B5F8000008000100000ABCD0000")'
- ID: BTSTK_GAP_03001
<<: *GAP_CASE
test point 2: BLE GAP set advertise param
@ -564,6 +705,7 @@ test cases:
- 'P BLENIC PDU (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.address_0{%s}<dut1_bt_mac>)'
- ID: BTSTK_GAP_03005
<<: *GAP_CASE
CI ready: "No"
test point 2: BLE GAP set advertise param
summary: ble set adv parameter adv interval
steps: |
@ -644,6 +786,156 @@ test cases:
- - "HCITOOL 2 -i <hci_nic> lescan"
- - 'P PC_COM C +HCITOOL:OK'
- 'P BLENIC {%s} (HCIEvent.le_sub_event_code="LEAdvReport")(HCIEvent.event_type_0="NONCONN_IND")(HCIEvent.address_0=<dut1_bt_mac>)'
- ID: BTSTK_GAP_03008
<<: *GAP_CASE
test point 2: BLE GAP set advertise param
summary: ble adv with random address and RPA_PUBLIC
initial condition: BLE_INIT_SMP
steps: |
1. DUT2 set random address
2. DUT2 adv with RPA_PUBLIC
3. DUT1 start scan
expected result: |
1. succeed
2. succeed
3. succeed
cmd set:
- ""
- - "SSC SSC2 bleadv -D -z stop"
- ["R SSC2 C +BLEADV:Stop,OK"]
- - "SSC SSC2 ble -S -z privacy -p 1"
- ["R SSC2 C +BLECONN:SetResAddr,Success"]
- - "SSC SSC2 bleadv -D -z start -t 0 -o 2"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC1 blescan -D -z start"
- ["R SSC1 P <dut2_bt_mac> C Complete"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK", "R SSC2 C +BLE:GattsConnect"]
- ID: BTSTK_GAP_03009
<<: *GAP_CASE
test point 2: BLE GAP set advertise param
summary: ble set adv owner address type as RPA_PUBLIC
initial condition: BLE_INIT_SMP
steps: |
1. DUT2 set owner address type as RPA_PUBLIC and start adv
2. DUT1 scan
3. exchange IRK and pairing
4. DUT2 set privacy
5. DUT2 set owner address type as RPA_PUBLIC and start adv
6. DUT1 scan
7. DUT1 connect to DUT2
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. succeed
6. succeed
7. succeed
cmd set:
- ""
- - "SSC SSC2 blesmp -S -z AuthReqMode -v 0x01"
- ['P SSC2 C +BLESMP:OK']
- - "SSC SSC2 blesmp -S -z IOCAP -v 0x03"
- ['P SSC2 C +BLESMP:OK']
- - "SSC SSC2 blesmp -S -z RspKey -v 0x03"
- ['P SSC2 C +BLESMP:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ['P SSC1 C +BLE:GattcConnect,OK', 'P SSC2 C +BLE:GattsConnect']
- - "SSC SSC2 blesmp -E -r <dut1_bt_mac> -z Enc"
- ['P SSC1 C +BLESMP:SecReq']
- - "SSC SSC1 blesmp -R -a 1 -r <dut2_bt_mac>"
- ['P SSC[1-2] C +BLESMP:AuthComplete,Success,0']
- - "SSC SSC1 bleconn -D -z all"
- ['P SSC1 C +BLE:GattcDisconnect,OK', 'P SSC2 C +BLE:GattsDisconnect,OK']
- - "SSC SSC2 ble -S -z privacy -p 1"
- ["R SSC2 C +BLECONN:SetResAddr,Success"]
- - "SSC SSC2 bleadv -D -z stop"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC2 bleadv -D -z start -o 2"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC1 blescan -D -z start"
- ["R SSC1 P <dut2_bt_mac> C Complete"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK", "R SSC2 C +BLE:GattsConnect"]
- ID: BTSTK_GAP_03010
<<: *GAP_CASE
CI ready: "No" # can't restore to use public address after set to use private address
test point 2: BLE GAP set advertise param
summary: ble adv with privacy address and RPA_RANDOM
initial condition: BLE_INIT_SMP
steps: |
1. DUT2 set random address
2. DUT2 adv with RPA_RANDOM
3. DUT1 start scan
expected result: |
1. succeed
2. succeed
3. succeed
cmd set:
- ""
- - "SSC SSC2 bleadv -D -z stop"
- ["R SSC2 C +BLEADV:Stop,OK"]
- - "SSC SSC2 ble -S -z privacy -p 1"
- ["R SSC2 C +BLECONN:SetResAddr,Success"]
- - "SSC SSC2 bleadv -D -z start -t 0 -o 3"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC1 blescan -D -z start"
- ["R SSC1 P <dut2_bt_mac> C Complete"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK", "R SSC2 C +BLE:GattsConnect"]
- ID: BTSTK_GAP_03011
<<: *GAP_CASE
CI ready: "No" # can't restore to use public address after set to use private address
test point 2: BLE GAP set advertise param
summary: ble set adv owner address type as RPA_RANDOM
initial condition: BLE_INIT_SMP
steps: |
1. DUT2 set owner address type as RPA_RANDOM and start adv
2. DUT2 set static random address
3. DUT2 set owner address type as RPA_RANDOM and start adv
4. DUT1 start scan
5. exchange IRK and do pairing
6. DUT2 set privacy
7. DUT2 set owner address type as RPA_RANDOM and start adv
8. DUT1 scan
9. DUT1 connect to DUT2
expected result: |
1. failed
2. succeed
3. succeed
4. succeed
5. succeed
6. succeed
7. succeed
8. succeed
9. succeed
cmd set:
- ""
- - "SSC SSC2 blesmp -S -z AuthReqMode -v 0x01"
- ['P SSC2 C +BLESMP:OK']
- - "SSC SSC2 blesmp -S -z IOCAP -v 0x03"
- ['P SSC2 C +BLESMP:OK']
- - "SSC SSC2 blesmp -S -z RspKey -v 0x03"
- ['P SSC2 C +BLESMP:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ['P SSC1 C +BLE:GattcConnect,OK', 'P SSC2 C +BLE:GattsConnect']
- - "SSC SSC2 blesmp -E -r <dut1_bt_mac> -z Enc"
- ['P SSC1 C +BLESMP:SecReq']
- - "SSC SSC1 blesmp -R -a 1 -r <dut2_bt_mac>"
- ['P SSC[1-2] C +BLESMP:AuthComplete,Success,0']
- - "SSC SSC1 bleconn -D -z all"
- ['P SSC1 C +BLE:GattcDisconnect,OK', 'P SSC2 C +BLE:GattsDisconnect,OK']
- - "SSC SSC2 ble -S -z privacy -p 1"
- ["R SSC2 C +BLECONN:SetResAddr,Success"]
- - "SSC SSC2 bleadv -D -z stop"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC2 bleadv -D -z start -o 3"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC1 blescan -D -z start"
- ["R SSC1 P <dut2_bt_mac> C Complete"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK", "R SSC2 C +BLE:GattsConnect"]
- ID: BTSTK_GAP_04001
<<: *GAP_CASE
test point 2: BLE GAP set scan param
@ -754,7 +1046,7 @@ test cases:
3. fail
4. fail
initial condition: BLE_INIT1
test environment: SSC_T1_1
test environment: SSC_T1_4
cmd set:
- ""
- - "SSC SSC1 blescan -L -c 0 -w 0x0004"
@ -784,7 +1076,6 @@ test cases:
5. succeed
6. DUT1 in scan result
initial condition: BLE_INIT2
test environment: SSC_T2_1
cmd set:
- ""
- *dut1_stop_adv
@ -812,7 +1103,7 @@ test cases:
2. succeed
3. failed
initial condition: BLE_INIT1
test environment: SSC_T1_1
test environment: SSC_T1_4
cmd set:
- ""
- - "SSC SSC1 blescan -L -c 0"
@ -881,7 +1172,7 @@ test cases:
<<: *GAP_CASE
allow fail: 1/2
test point 2: BLE GAP connect / disconnect
summary: ble connect/disconnect to same connection multiple times
summary: ble connect/disconnect to same connection multiple times
steps: |
1. DUT1 connect to DUT2 as "client"
2. DUT1 start gatt server app
@ -1674,7 +1965,7 @@ test cases:
2. fail
3. fail
initial condition: BLE_DEINIT1
test environment: SSC_T1_1
test environment: SSC_T1_4
cmd set:
- ""
- - "SSC SSC1 bleadv -L -c 0"
@ -1702,7 +1993,7 @@ test cases:
3. fail
4. fail
initial condition: BLE_DEINIT1
test environment: SSC_T1_1
test environment: SSC_T1_4
cmd set:
- ""
- - "SSC SSC1 bt -D -z init"
@ -1732,7 +2023,7 @@ test cases:
3. fail
4. fail
initial condition: BLE_DEINIT1
test environment: SSC_T1_1
test environment: SSC_T1_4
cmd set:
- ""
- - "SSC SSC1 bt -D -z start"
@ -1941,7 +2232,7 @@ test cases:
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- - "SSC SSC2 blescan -D -z start -t 1 -e 1"
- - 'P SSC2 RE "\+BTSCANEXT:%%s,txp,0xEB"%%(<dut1_bt_mac>)'
- - 'P SSC2 RE "\+BTSCANEXT:%%s,txp,0xEB"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -x 0 -t 3"
@ -2111,6 +2402,150 @@ test cases:
- 'P SSC2 RE "\+BTSCANEXT:%%s,srv32,0xABCDDCBA"%%(<dut1_bt_mac>)'
- 'P SSC2 RE "\+BTSCANEXT:%%s,srv128,0x12349B5F8000008000100000ABCD0000"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- ID: BTSTK_GAP_09012
<<: *GAP_CASE
test point 2: BLE GAP processing scan data
summary: adv include name and not set device name
steps: |
1. DUT1 stop advertise
2. DUT1 set advertising data and scan response include name
3. DUT1 start advertising
4. DUT2 start scan and processing scan data
expected result: |
1. succeed
2. succeed
3. succeed
4. failed
cmd set:
- ""
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -n 1 -t 3"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- - "SSC SSC1 bleadv -D -z start"
- ["R SSC1 C +BLEADV:Start,OK"]
- - "SSC SSC2 blescan -D -z start"
- - 'P SSC2 RE "\+BTSCAN:INQ,%%s"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- ID: BTSTK_GAP_09013
<<: *GAP_CASE
test point 2: BLE GAP processing scan data
summary: adv manufacturer_len not equal to real len
steps: |
1. DUT1 stop adv
2. DUT1 set manufacturer len shorter then real len
3. DUT1 start adv
4. DUT2 start scan
5. DUT1 stop adv
6. DUT1 set manufacturer len longer then real len
7. DUT1 start adv
8. DUT2 start scan
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. succeed
6. succeed
7. succeed
8. succeed
cmd set:
- ""
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -m 0x12345678 -t 3 -l 6"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- - "SSC SSC2 blescan -D -z start -e 1"
- - 'P SSC2 RE "\+BTSCANEXT:%%s,man,0x12345678"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -m 0x12345678 -t 3 -l 10"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- - "SSC SSC2 blescan -D -z start -e 1"
- - 'P SSC2 RE "\+BTSCANEXT:%%s,man,0x12345678"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- ID: BTSTK_GAP_09014
<<: *GAP_CASE
test point 2: BLE GAP processing scan data
summary: set adv service data length not equal to real length
steps: |
1. DUT1 stop advertise
2. DUT1 set advertising data and scan response service data 0x1234123456 and set service data length 4
3. DUT1 start advertising
4. DUT2 start scan and processing scan data
5. DUT1 stop advertise
6. DUT1 set advertising data and scan response service data 0x1234123456 and set service data length 10
7. DUT1 start advertising
8. DUT2 start scan and processing scan data
expected result: |
1. succeed
2. succeed
3. succeed
4. scan with the correct adv data
5. succeed
6. succeed
7. succeed
8. scan with the correct adv data
cmd set:
- ""
- *dut1_stop_adv
- *set_default_ble_name
- - "SSC SSC1 bleadv -L -c 0 -n 0 -d 0x1234123456 -t 3 -l 4"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- - "SSC SSC2 blescan -D -z start -t 1 -e 1"
- - 'P SSC2 RE "\+BTSCANEXT:%%s,srvdata,0x1234123456"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- *dut1_stop_adv
- *set_default_ble_name
- - "SSC SSC1 bleadv -L -c 0 -n 0 -d 0x1234123456 -t 3 -l 10"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- - "SSC SSC2 blescan -D -z start -t 1 -e 1"
- - 'P SSC2 RE "\+BTSCANEXT:%%s,srvdata,0x1234123456"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- ID: BTSTK_GAP_09015
<<: *GAP_CASE
test point 2: BLE GAP processing scan data
summary: set service uuid length not equal to real length
steps: |
1. DUT1 stop advertise
2. DUT1 set advertising data and scan response not include name, service uuid list 0xABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 and set service uuid length 32
3. DUT1 start advertising
4. DUT2 start scan and processing scan data
5. DUT1 stop advertise
6. DUT1 set advertising data and scan response not include name, service uuid list 0xABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 and set service uuid length 64
7. DUT1 start advertising
8. DUT2 start scan and processing scan data
expected result: |
1. succeed
2. succeed
3. succeed
4. scan with the correct adv data
5. succeed
6. succeed
7. succeed
8. scan with the correct adv data
cmd set:
- ""
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -n 0 -x 0 -i 0x00-0x00 -s ABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 -t 3 -l 32"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- - "SSC SSC2 blescan -D -z start -t 1 -e 1"
- - 'P SSC2 RE "\+BTSCANEXT:%%s,srv16,0xABCD"%%(<dut1_bt_mac>)'
- 'P SSC2 RE "\+BTSCANEXT:%%s,srv32,0xABCDDCBA"%%(<dut1_bt_mac>)'
- 'P SSC2 RE "\+BTSCANEXT:%%s,srv128,0x12349B5F8000008000100000ABCD0000"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- *dut1_stop_adv
- - "SSC SSC1 bleadv -L -c 0 -n 0 -x 0 -i 0x00-0x00 -s ABCD,ABCDDCBA,12349B5F8000008000100000ABCD0000 -t 3 -l 64"
- ["R SSC1 C +BLEADV:SetAdv,OK"]
- *dut1_start_adv
- - "SSC SSC2 blescan -D -z start -t 1 -e 1"
- - 'P SSC2 RE "\+BTSCANEXT:%%s,srv16,0xABCD"%%(<dut1_bt_mac>)'
- 'P SSC2 RE "\+BTSCANEXT:%%s,srv32,0xABCDDCBA"%%(<dut1_bt_mac>)'
- 'P SSC2 RE "\+BTSCANEXT:%%s,srv128,0x12349B5F8000008000100000ABCD0000"%%(<dut1_bt_mac>)'
- 'R SSC2 C Complete'
- ID: BTSTK_GAP_10001
<<: *GAP_CASE
test point 2: BLE GAP master multi connection test
@ -2341,6 +2776,7 @@ test cases:
- ["P SSC1 C Disconnect"]
- ID: BTSTK_GAP_40001
<<: *GAP_CASE
auto test: 'No'
test point 2: test if BLE work after switch off some sub modules
summary: GAP only test
steps: |
@ -2404,6 +2840,42 @@ test cases:
- ""
- - "fail_timeout = 10"
- ""
- ID: BTSTK_GAP_50004
<<: *GAP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GAP performance test
summary: BLE Connect and disconnect correct performance test
steps: |
1. DUT1 disconnect with DUT2
2. DUT2 start advertising
3. DUT1 connect to DUT2
4. loop step 1-4 1000 times
5. reboot
6. loop step 1-5
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. succeed
6. meet pass standard
initial condition: BLE_INIT2
execution time: 6
version: v1 (2017-05-19)
CI ready: 'No'
cmd set:
- "BLEStress/BLEConnCorPerformance"
- - "test_time = 100"
- ""
- - "reboot_time = 1000"
- ""
- - "average_conn_time = 3"
- ""
- - "fail_ratio = 0.01"
- ""
- - "fail_timeout = 10"
- ""
- ID: BTSTK_GAP_51001
<<: *GAP_CASE
category: Performance
@ -2512,7 +2984,7 @@ test cases:
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC1 blescan -D -z start"
- ['R SSC1 P <static_device_addr> C Complete']
- - "SSC SSC1 bleconn -C -p 0x10 -a <static_device_addr>"
- - "SSC SSC1 bleconn -C -p 0x10 -a <static_device_addr> -r 1"
- ["P SSC1 C +BLE:GattcConnect,OK", "P SSC2 C +BLE:GattsConnect"]
- ID: BTSTK_GAP_14002
<<: *GAP_CASE
@ -2604,19 +3076,21 @@ test cases:
- ID: BTSTK_GAP_14008
<<: *GAP_CASE
test point 2: BLE set random address test
summary: disconnect after encryption and set random address as resolvable private address and reconnect
summary: BLE set random address as resolvable private address and reconnect after disconnect
steps: |
1. SSC2 set AuthReqMode and IOCAP,set RspKey as Enc and IRK
2. pairing
3. SSC1 disconnect to SSC2
4. SSC2 do local privacy
5. SSC2 bleadv and SSC1 blescan
6. SSC1 connect to SSC2
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. succeed
6. succeed
initial condition: BLE_INIT_SMP
cmd set:
- ""
@ -2636,34 +3110,30 @@ test cases:
- ['P SSC1 C +BLE:GattcDisconnect,OK', 'P SSC2 C +BLE:GattsDisconnect,OK']
- - "SSC SSC2 ble -S -z privacy -p 1"
- ["R SSC2 C +BLECONN:SetResAddr,Success"]
- - "SSC SSC2 bleadv -D -z stop"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC2 bleadv -L -c 0 -t 3"
- ["R SSC2 C +BLEADV:SetAdv,OK C +BLEADV:SetScanRes,OK"]
- - "SSC SSC2 bleadv -D -z start -o 1"
- ["R SSC2 C +BLEADV:OK"]
- - "SSC SSC1 blescan -D -z stop"
- ["R SSC1 C +BLESCAN:OK"]
- - "SSC SSC1 blescan -L -c 0"
- ["R SSC1 C +BLESCAN:SetScanParam,OK"]
- - "SSC SSC1 blescan -D -z start -t 3"
- ["R SSC1 P <dut2_bt_mac>"]
- ["R SSC1 P <dut2_bt_mac> C InquiryComplete"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK", "R SSC2 C +BLE:GattsConnect"]
- ID: BTSTK_GAP_14009
<<: *GAP_CASE
test point 2: BLE set random address test
summary: reboot after BLE DUT encryption and set random address as resolvable private address
summary: BLE set random address as resolvable private address and reconnect after reboot
steps: |
1. SSC2 set AuthReqMode and IOCAP,set RspKey as Enc and IRK
2. pairing
3. SSC1 and SSC2 reboot
4. SSC2 do local privacy
5. SSC2 bleadv and SSC1 blescan
6. SSC1 connect to SSC2
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. succeed
6. succeed
initial condition: BLE_INIT_SMP
allow fail: 2/3
cmd set:
@ -2684,6 +3154,8 @@ test cases:
- ['R SSC[1-2] C !!!ready!!!']
- - "SSC SSC[1-2] ble -R"
- ["R SSC[1-2] C +BLE:OK"]
- - "SSC SSC2 gatts -S -z load -p 0xA0"
- ['R SSC2 C +GATTS:LoadProfile,OK']
- - "SSC SSC2 ble -S -z privacy -p 1"
- ["R SSC2 C +BLECONN:SetResAddr,Success"]
- - "SSC SSC2 bleadv -D -z stop"
@ -2697,7 +3169,9 @@ test cases:
- - "SSC SSC1 blescan -L -c 0"
- ["R SSC1 C +BLESCAN:SetScanParam,OK"]
- - "SSC SSC1 blescan -D -z start -t 3"
- ["R SSC1 P <dut2_bt_mac>"]
- ["R SSC1 P <dut2_bt_mac> C InquiryComplete"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK", "R SSC2 C +BLE:GattsConnect"]
- ID: BTSTK_GAP_15001
<<: *GAP_CASE
test point 2: BLE GAP white list test
@ -2714,7 +3188,7 @@ test cases:
4. succeed
initial condition: BLE_INIT_REBOOT2
cmd set:
- ""
- ""
- - "SSC SSC1 ble -W -z get"
- ['P SSC1 C +BLE:GetWhiteList,OK,12']
- - "SSC SSC1 ble -W -a <dut2_bt_mac> -z add"

View file

@ -5,7 +5,7 @@
category: Function
test point 1: basic function
initial condition: BLE_CONN2
test environment: SSC_T2_1
test environment: SSC_T2_5
execution time: 0
module: BT Stack
sub module: GATT
@ -19,14 +19,47 @@
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:Discover,OK"]
.included_service_connection: &included_service_connection
.included_service_connection: &included_primary_service_connection
LIST_MERGE:
- - "SSC SSC2 gatts -S -z load -p 0xA1"
- ["R SSC2 C +GATTS:StartService,OK,A001"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- ["R SSC2 C +GATTS:LoadProfile,OK,A001", "R SSC2 C +GATTS:StartService,OK,A001"]
- - "SSC SSC2 gatts -S -z include -p 0xA1 -i 0xA0"
- ["R SSC2 C +GATTS:AddIncludedService,OK"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
.included_second_service_connection: &included_second_service_connection
LIST_MERGE:
- - "SSC SSC2 gatts -S -z load -p 0xA4"
- ["R SSC2 C +GATTS:StartService,OK,A004"]
- - "SSC SSC2 gatts -S -z load -p 0xA1"
- ["R SSC2 C +GATTS:LoadProfile,OK,A001", "R SSC2 C +GATTS:StartService,OK,A001"]
- - "SSC SSC2 gatts -S -z include -p 0xA1 -i 0xA4"
- ["R SSC2 C +GATTS:AddIncludedService,OK"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
.table_include_table_service: &table_include_table_service
LIST_MERGE:
- - "SSC SSC2 gatts -S -z load -p 0xA5 -i 0xA2"
- ["R SSC2 C +GATTS:StartService,OK,A005"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
.table_include_service: &table_include_service
LIST_MERGE:
- - "SSC SSC2 gatts -S -z load -p 0xA5 -i 0xA0"
- ["R SSC2 C +GATTS:StartService,OK,A005"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
.register_notify_c107: &register_notify_c107
LIST_MERGE:
@ -47,7 +80,7 @@ test cases:
expected result: |
1. succeed
initial condition: BLE_INIT1
test environment: SSC_T1_1
test environment: SSC_T1_4
cmd set:
- ""
- - "SSC SSC1 gatts -S -z load -p 0xA0"
@ -63,7 +96,7 @@ test cases:
1. succeed
2. succeed
initial condition: BLE_INIT1
test environment: SSC_T1_1
test environment: SSC_T1_4
cmd set:
- ""
- - "SSC SSC1 gatts -S -z load -p 0xA0"
@ -73,7 +106,7 @@ test cases:
- ID: BTSTK_GATT_20001
<<: *GATT_CASE
test point 2: BLE GATT client service / char discovery
summary: GATT client discover primary service
summary: GATT client discover manual primary service
steps: |
1. DUT2 create preset service 0xA000
2. DUT2 create preset service 0xA001
@ -87,14 +120,13 @@ test cases:
initial condition: BLE_INIT2
cmd set:
- ""
- *included_service_connection
- *included_primary_service_connection
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:DiscoverService,A000 C +GATTC:DiscoverService,A001"]
- ID: BTSTK_GATT_20002
<<: *GATT_CASE
test point 2: BLE GATT client service / char discovery
summary: GATT client get included service
allow fail: 1/2
summary: GATT client get manual included service
steps: |
1. DUT2 create preset service 0xA000
2. DUT2 create preset service 0xA001
@ -110,11 +142,99 @@ test cases:
initial condition: BLE_INIT2
cmd set:
- ""
- *included_service_connection
- *included_primary_service_connection
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:DiscoverService,A000 A <handle_range>:GATTC:DiscoverService,A001,(\\d+-\\d+)"]
- - "SSC SSC1 gattc -D -z includedService -p 0x10 -s 0xA001 -i 0xA000 -q <handle_range> -k 1"
- ["R SSC1 C +GATTC:IncludedService,0010,A001,A000"]
- ID: BTSTK_GATT_20003
<<: *GATT_CASE
test point 2: BLE GATT client service / char discovery
summary: GATT client discover table primary service (table service include table service)
steps: |
1. DUT2 create preset service 0xA002
2. DUT2 create preset service 0xA005
3. DUT1 connect to DUT2
4. DUT1 do primary service discovery
expected result: |
1. succeed
2. succeed
3. succeed
4. found service 0xA002 and 0xA005
initial condition: BLE_INIT3
cmd set:
- ""
- *table_include_table_service
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:DiscoverService,A002 C +GATTC:DiscoverService,A005"]
- ID: BTSTK_GATT_20004
<<: *GATT_CASE
test point 2: BLE GATT client service / char discovery
summary: GATT client get table included service
steps: |
1. DUT2 create preset service 0xA002
2. DUT2 create preset service 0xA005
3. DUT1 connect to DUT2
4. DUT1 do primary service discovery
5. DUT1 get included service 0xA002 from service 0xA005
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. get included service 0xA002 from service 0xA005
initial condition: BLE_INIT3
cmd set:
- ""
- *table_include_table_service
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:DiscoverService,A002 A <handle_range>:GATTC:DiscoverService,A005,(\\d+-\\d+)"]
- - "SSC SSC1 gattc -D -z includedService -p 0x10 -s 0xA005 -i 0xA002 -q <handle_range> -k 1"
- ["R SSC1 C +GATTC:IncludedService,0010,A005,A002"]
- ID: BTSTK_GATT_20005
<<: *GATT_CASE
test point 2: BLE GATT client service / char discovery
summary: GATT client discover table primary service (table service include manual service)
steps: |
1. DUT2 create preset service 0xA000
2. DUT2 create preset service 0xA005
3. DUT1 connect to DUT2
4. DUT1 do primary service discovery
expected result: |
1. succeed
2. succeed
3. succeed
4. found service 0xA000 and 0xA005
initial condition: BLE_INIT2
cmd set:
- ""
- *table_include_service
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:DiscoverService,A000 C +GATTC:DiscoverService,A005"]
- ID: BTSTK_GATT_20006
<<: *GATT_CASE
test point 2: BLE GATT client service / char discovery
summary: GATT client get table included manual service
steps: |
1. DUT2 create preset service 0xA000
2. DUT2 create preset service 0xA005
3. DUT1 connect to DUT2
4. DUT1 do primary service discovery
5. DUT1 get included service 0xA000 from service 0xA005
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. get included service 0xA000 from service 0xA005
initial condition: BLE_INIT2
cmd set:
- ""
- *table_include_service
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:DiscoverService,A000 A <handle_range>:GATTC:DiscoverService,A005,(\\d+-\\d+)"]
- - "SSC SSC1 gattc -D -z includedService -p 0x10 -s 0xA005 -i 0xA000 -q <handle_range> -k 1"
- ["R SSC1 C +GATTC:IncludedService,0010,A005,A000"]
- ID: BTSTK_GATT_60001
<<: *GATT_CASE
test point 2: BLE GATT server get and set value
@ -594,10 +714,10 @@ test cases:
- ""
- - "SSC SSC2 gatts -S -z load -p 0xA1"
- ["R SSC2 C +GATTS:StartService,OK,A001"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- *primary_service_discovery
- - "SSC SSC1 gattc -R -z char -s 0xA000 -c 0xC100 -p 0x10"
- ["R SSC1 C +GATTC:ReadOnce,0010,A000,C100,1", "R SSC1 C +GATTC:Read,OK,0010,A000,C100"]
@ -623,10 +743,10 @@ test cases:
- ""
- - "SSC SSC2 gatts -S -z load -p 0xA1"
- ["R SSC2 C +GATTS:StartService,OK,A001"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- *primary_service_discovery
- - "SSC SSC1 gattc -R -z descriptor -s 0xA000 -c 0xC107 -d 0x2902 -p 0x10"
- ["R SSC1 C +GATTC:ReadOnce,0010,A000,C107,2902,2", "R SSC1 C +GATTC:ReadDescriptor,OK,0010,A000,C107,2902"]
@ -889,10 +1009,10 @@ test cases:
- ""
- - "SSC SSC2 gatts -S -z load -p 0xA1"
- ["R SSC2 C +GATTS:StartService,OK,A001"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- *primary_service_discovery
- - "SSC SSC1 gattc -W -z char -s 0xA000 -c 0xC102 -p 0x10 -v 0x01"
- ["R SSC1 C +GATTC:WriteOnce,0010,A000,C102", "R SSC1 C +GATTC:Write,OK,0010,A000,C102"]
@ -917,10 +1037,10 @@ test cases:
- ""
- - "SSC SSC2 gatts -S -z load -p 0xA1"
- ["R SSC2 C +GATTS:StartService,OK,A001"]
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- - SSC SSC1 gattc -F -r <dut2_bt_mac>
- ['R SSC1 C +GATTC:OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a <dut2_bt_mac>"
- ["R SSC1 C +BLE:GattcConnect,OK,0010", "R SSC2 C +BLE:GattsConnect"]
- *primary_service_discovery
- - "SSC SSC1 gattc -W -z descriptor -s 0xA000 -c 0xC107 -d 0x2902 -p 0x10 -v 0x0100"
- ["R SSC1 C +GATTC:WriteOnce,0010,A000,C107,2902", "R SSC1 C +GATTC:WriteDescriptor,OK,0010,A000,C107,2902"]
@ -1217,7 +1337,7 @@ test cases:
- ID: BTSTK_GATT_23004
<<: *GATT_CASE
test point 2: BLE GATT client receive notify and indication
summary: GATT client can't receive notification/indication without write to CCC
summary: GATT client can't receive notification/indication without write to CCC (manual service)
steps: |
1. DUT1 do service discovery
2. DUT1 register notify on notify and inidcation char
@ -1284,7 +1404,7 @@ test cases:
- ID: BTSTK_GATT_23007
<<: *GATT_CASE
test point 2: BLE GATT client receive notify and indication
summary: GATT client can't receive notification/indication without write to CCC
summary: GATT client can't receive notification/indication without write to CCC (auto service auto reply)
steps: |
1. DUT1 do service discovery
2. DUT1 register notify on notify and inidcation char
@ -1352,7 +1472,7 @@ test cases:
- ID: BTSTK_GATT_23010
<<: *GATT_CASE
test point 2: BLE GATT client receive notify and indication
summary: GATT client can't receive notification/indication without write to CCC
summary: GATT client can't receive notification/indication without write to CCC (auto service manual reply)
steps: |
1. DUT1 do service discovery
2. DUT1 register notify on notify and inidcation char
@ -1685,9 +1805,9 @@ test cases:
cmd set:
- ""
- *primary_service_discovery
- - "SSC SSC1 gattc -W -z char -s 0xA002 -c 0xC302 -p 0x10 -v 0x01 -w 1"
- - "SSC SSC1 gattc -W -z char -s 0xA002 -c 0xC302 -p 0x10 -v -x01 -w 1"
- ["R SSC1 C +GATTC:Write,OK"]
- - "SSC SSC1 gattc -W -z char -s 0xA002 -c 0xC302 -p 0x10 -v 0x01 -w 1"
- - "SSC SSC1 gattc -W -z char -s 0xA002 -c 0xC302 -p 0x10 -v -x01 -w 1"
- ["R SSC1 C +GATTC:Write,OK"]
- ID: BTSTK_GATT_25015
<<: *GATT_CASE
@ -1880,6 +2000,61 @@ test cases:
- ["R SSC1 C +GATTC:WriteOnce,0010,A000,C109"]
- - "SSC SSC1 gattc -W -z char -p 0x10 -s 0xA000 -c 0xC109 -l 512"
- ["R SSC1 C +GATTC:WriteOnce,0010,A000,C109"]
- ID: BTSTK_GATT_27001
<<: *GATT_CASE
test point 2: BLE GATT read multiple
summary: GATT client read 2 char and 11 char of same service
steps: |
1. DUT1 do discover
2. GATT client read 2 char
3. GATT client read 11 char
expected result: |
1. succeed
2. succeed
3. succeed
cmd set:
- ""
- *primary_service_discovery
- - "SSC SSC1 gattc -R -z multiple -u #0xC100##0xC101# -s 0xA000"
- ['R SSC1 C +GATTC:ReadOnce,22', 'R SSC1 C +GATTC:ReadMultiple,OK']
- - "SSC SSC1 gattc -R -z multiple -u #0xC100##0xC101##0xC107##0xC108##0xC109##0xC110##0xC100##0xC101##0xC107##0xC108##0xC109# -s 0xA000"
- ['R SSC1 C +GATTC:Read,ERROR']
- ID: BTSTK_GATT_27002
<<: *GATT_CASE
test point 2: BLE GATT read multiple
summary: GATT client read char and descriptor
steps: |
1. DUT1 do discover
2. GATT client read all char and descriptor
expected result: |
1. succeed
2. succeed
cmd set:
- ""
- *primary_service_discovery
- - "SSC SSC1 gattc -R -z multiple -u 0xA00xC100#0xA00xC101#0xA00xC1000x29010xA00xC1070x2902"
- ['R SSC1 C +GATTC:ReadOnce', 'R SSC1 C +GATTC:ReadMultiple,OK']
- ID: BTSTK_GATT_27003
<<: *GATT_CASE
test point 2: BLE GATT read multiple
summary: GATT client read char and descriptor of included service and table service
initial condition: BLE_INIT2
steps: |
1. DUT2 load service included service and table service
2. DUT1 search service
3. GATT client read all char and descriptor of different services
expected result: |
1. succeed
2. succeed
3. succeed
cmd set:
- ""
- - "SSC SSC2 gatts -S -z load -p 0xA2"
- ['R SSC2 C +GATTS:StartService,OK,A002']
- *included_primary_service_connection
- *primary_service_discovery
- - "SSC SSC1 gattc -R -z multiple -u 0xA10xC200#0xA00xC100#0xA00xC101#0xA20xC300#0xA20xC301#"
- ['R SSC1 C +GATTC:ReadOnce', 'R SSC1 C +GATTC:ReadMultiple,OK']
- ID: BTSTK_GATT_30001
<<: *GATT_CASE
test point 2: BLE GATT multi connection service discovery test
@ -2071,7 +2246,7 @@ test cases:
- ID: BTSTK_GATT_32002
<<: *GATT_CASE
test point 2: BLE GATT multi connection write test
summary: do read when DUT1 is slave, connected by 4 masters
summary: do write when DUT1 is slave, connected by 4 masters
steps: |
1. do primary service discovery on DUT[2-5]
expected result: |
@ -2121,7 +2296,7 @@ test cases:
- ID: BTSTK_GATT_32004
<<: *GATT_CASE
test point 2: BLE GATT multi connection write test
summary: do read when master and slave both create GATTC and GATTS
summary: do write when master and slave both create GATTC and GATTS
steps: |
1. DUT1 do primary service discovery for DUT2
2. DUT2 do primary service discovery for DUT1
@ -2230,7 +2405,7 @@ test cases:
- ID: BTSTK_GATT_33004
<<: *GATT_CASE
test point 2: BLE GATT multi connection notify test
summary: do read when master and slave both create GATTC and GATTS
summary: do notify when master and slave both create GATTC and GATTS
steps: |
1. DUT1 do primary service discovery for DUT2
2. DUT2 do primary service discovery for DUT1
@ -2253,7 +2428,7 @@ test cases:
- ID: BTSTK_GATT_34001
<<: *GATT_CASE
test point 2: BLE GATT multi connection indicate test
summary: do notify when DUT1 role is master, connected with 4 slaves
summary: do indicate when DUT1 role is master, connected with 4 slaves
steps: |
1. do primary service discovery
2. do register indication for char
@ -2277,7 +2452,7 @@ test cases:
- ID: BTSTK_GATT_34002
<<: *GATT_CASE
test point 2: BLE GATT multi connection indicate test
summary: do notify when DUT1 is slave, connected by 4 masters
summary: do indicate when DUT1 is slave, connected by 4 masters
steps: |
1. do primary service discovery on DUT[2-5]
2. DUT[2-5] do register indication
@ -2301,7 +2476,7 @@ test cases:
- ID: BTSTK_GATT_34003
<<: *GATT_CASE
test point 2: BLE GATT multi connection indicate test
summary: do notify when DUT1 connect to DUT[2-3] and connected by DUT[4-5]
summary: do indicate when DUT1 connect to DUT[2-3] and connected by DUT[4-5]
steps: |
1. DUT1 do primary service discovery for DUT[2-3]
2. DUT1 register indication
@ -2339,7 +2514,7 @@ test cases:
- ID: BTSTK_GATT_34004
<<: *GATT_CASE
test point 2: BLE GATT multi connection indicate test
summary: do read when master and slave both create GATTC and GATTS
summary: do indicate when master and slave both create GATTC and GATTS
steps: |
1. DUT1 do primary service discovery for DUT2
2. DUT2 do primary service discovery for DUT1
@ -2533,7 +2708,7 @@ test cases:
- ""
- - gatt_op = "write"
- ""
- - op_char = "0xC304"
- - op_char = "0xC317"
- ""
- - op_len = 490
- ""
@ -2564,7 +2739,7 @@ test cases:
- ""
- - op_char = "0xC305"
- ""
- - op_len = 256
- - op_len = 490
- ""
- ID: BTSTK_GATT_50004
<<: *GATT_CASE
@ -2595,3 +2770,267 @@ test cases:
- ""
- - op_len = 256
- ""
- ID: BTSTK_GATT_50005
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: GATT master connect 4 slave and read char performance test
initial condition: BLE_CONN5
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "read"
- ""
- - op_char = "0xC301"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC1"]
- ""
- - slave_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- ID: BTSTK_GATT_50006
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: GATT 4 master connect 1 slave and read char performance test
initial condition: BLE_CONN6
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "read"
- ""
- - op_char = "0xC301"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- - slave_duts = ["SSC1"]
- ""
- ID: BTSTK_GATT_50007
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: GATT master connect 4 slave and write char performance test
initial condition: BLE_CONN5
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "write"
- ""
- - op_char = "0xC304"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC1"]
- ""
- - slave_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- ID: BTSTK_GATT_50008
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: GATT 4 master connect 1 slave and write char performance test
initial condition: BLE_CONN6
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "write"
- ""
- - op_char = "0xC304"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- - slave_duts = ["SSC1"]
- ""
- ID: BTSTK_GATT_50009
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: notify performance test when GATT master connects to 4 slaves
initial condition: BLE_CONN5
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "notify"
- ""
- - op_char = "0xC305"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC1"]
- ""
- - slave_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- ID: BTSTK_GATT_50010
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: notify performance test when GATT 4 masters connect to 1 slave
initial condition: BLE_CONN6
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "notify"
- ""
- - op_char = "0xC305"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- - slave_duts = ["SSC1"]
- ""
- ID: BTSTK_GATT_50011
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: indicate performance test when GATT master connects 4 slaves
initial condition: BLE_CONN5
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "indicate"
- ""
- - op_char = "0xC306"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC1"]
- ""
- - slave_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- ID: BTSTK_GATT_50012
<<: *GATT_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE GATT performance test
summary: indicate performance test when GATT 4 masters connect 1 slave
initial condition: BLE_CONN6
test environment: SSC_T5_1
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLEMultiPerformance"
- - test_time = 120
- ""
- - mtu = 512
- ""
- - gatt_op = "indicate"
- ""
- - op_char = "0xC306"
- ""
- - op_len = 256
- ""
- - master_duts = ["SSC2", "SSC3", "SSC4", "SSC5"]
- ""
- - slave_duts = ["SSC1"]
- ""

View file

@ -17,8 +17,8 @@
test cases:
- ID: BTSTK_MISC_0101
<<: *MISC_CASE
test point 2: bt init and enable
summary: correct init and deinit flow
test point 2: bt host init and enable
summary: correct host init and deinit flow
steps: |
1. disable and deinit bt
2. init bt
@ -45,8 +45,8 @@ test cases:
- ["R SSC1 C +BT:OK"]
- ID: BTSTK_MISC_0102
<<: *MISC_CASE
test point 2: bt init and enable
summary: incorrect deinit disable flow
test point 2: bt host init and enable
summary: incorrect host deinit disable flow
steps: |
1. disable and deinit bt
2. init and enable bt
@ -85,8 +85,8 @@ test cases:
- ["R SSC1 C +BT:ERROR"]
- ID: BTSTK_MISC_0103
<<: *MISC_CASE
test point 2: bt init and enable
summary: incorrect init enable flow
test point 2: bt host init and enable
summary: incorrect host init enable flow
steps: |
1. disable and deinit bt
2. enable bt
@ -247,7 +247,7 @@ test cases:
- ID: BTSTK_MISC_0401
<<: *MISC_CASE
test point 2: bt controller init and enable
summary: incorrect init enable flow
summary: incorrect controller init enable flow
steps: |
1. disable and deinit btc
2. enable btc
@ -284,7 +284,7 @@ test cases:
- ID: BTSTK_MISC_0402
<<: *MISC_CASE
test point 2: bt controller init and enable
summary: correct init and deinit flow
summary: correct controller init and deinit flow
steps: |
1. disable and deinit btc
2. init btc
@ -312,7 +312,7 @@ test cases:
- ID: BTSTK_MISC_0403
<<: *MISC_CASE
test point 2: bt controller init and enable
summary: incorrect deinit disable flow
summary: incorrect controller deinit disable flow
steps: |
1. disable and deinit btc
2. init and enable btc

View file

@ -5,7 +5,7 @@
category: Function
test point 1: basic function
initial condition: BLE_INIT_SMP
test environment: SSC_T2_1
test environment: SSC_T2_5
execution time: 0
module: BT Stack
sub module: SMP
@ -70,7 +70,7 @@
.check_connection: &check_connection
LIST_MERGE:
- - "SSC SSC1 gattc -D -z primaryService -p 0x10"
- ["R SSC1 C +GATTC:DiscoverService,A000"]
- ["R SSC1 C +GATTC:DiscoverService,A002"]
.disconnect: &disconnect
LIST_MERGE:
@ -1619,7 +1619,7 @@ test cases:
- ID: BTSTK_SMP_03001
<<: *SMP_CASE
test point 2: BLE SMP pair with pairing request test
summary: BLE SMP start pair with pairing request
summary: BLE SMP start pair with secruity request
steps: |
1. set sec properity None on initiator and responder
2. set IOCAP to KeyboardDisplay on initiator and responder
@ -1666,7 +1666,7 @@ test cases:
- ID: BTSTK_SMP_04001
<<: *SMP_CASE
test point 2: BLE SMP key test
summary: BLE SMP set key size test
summary: BLE SMP set key size less than required
allow fail: 1/2
steps: |
1. set key size 7
@ -1691,7 +1691,7 @@ test cases:
- ID: BTSTK_SMP_04002
<<: *SMP_CASE
test point 2: BLE SMP key test
summary: BLE SMP set key size test
summary: BLE SMP set key size greater than required
allow fail: 1/2
steps: |
1. set key size 16
@ -1777,6 +1777,8 @@ test cases:
- - "SSC SSC1 blesmp -R -a 1 -r <dut2_bt_mac>"
- ['R SSC2 A <key>:BLESMP:NCReq,(\d+)', 'R SSC1 C NCReq P <key>']
- - "SSC SSC2 blesmp -K -r <dut1_bt_mac> -a {%d} -k 000001"
- []
- - DELAY 10
- ['P SSC[1-2] C +BLESMP:AuthComplete,Fail']
- *disconnect
- - LOOP 2 6 "[1,0]" "[0,1]"
@ -1864,7 +1866,7 @@ test cases:
- [""]
- ID: BTSTK_SMP_06001
<<: *SMP_CASE
test environment: SSC_T1_1
test environment: SSC_T1_4
initial condition: BLE_DEINIT1
test point 2: BLE SMP use API in abnormal state
summary: BLE SMP use API when BLE not initialized, not enabled or not registered callback
@ -2253,15 +2255,21 @@ test cases:
- ID: BTSTK_SMP_08003
<<: *SMP_CASE
test point 2: BLE SMP bond item management test
summary: BLE SMP get bond list and number
summary: BLE SMP get bond list and number when pairing and after reboot
steps: |
1. DUT2 set AuthReqMode and RspKey
2. pairing
3. get bong and remove bond
1. all slaves set AuthReqMode and RspKey
2. do pairing
3. master and slave get bond list and num
4. reboot
5. master and slave get bond list and num
6. slave remove bond device
expected result: |
1. Succeed
2. Succeed
3. Succeed
4. succeed
5. succeed
6. succeed
test environment: SSC_T5_1
initial condition: BLE_INIT_SMP5
cmd set:
@ -2286,12 +2294,18 @@ test cases:
- ['P SSC1 C +BLESMP:GetBondList,OK,4']
- - "SSC SSC1 blesmp -B -z getnum"
- ['P SSC1 C +BLESMP:GetBondNum,4']
- - "SSC SSC1 bleconn -D -z all"
- ['R SSC1 C +BLECONN:']
- - "SSC SSC1 blesmp -B -z remove -r <dut2_bt_mac>"
- ['P SSC1 RE "\+BLESMP:RemoveBond,Success,%%s"%%(<dut2_bt_mac>)']
- - "SSC SSC1 blesmp -B -z remove -r <dut3_bt_mac>"
- ['P SSC1 RE "\+BLESMP:RemoveBond,Success,%%s"%%(<dut3_bt_mac>)']
- - "SSC SSC2 blesmp -B -z getnum"
- ['P SSC2 C +BLESMP:GetBondNum,1']
- - "SSC SSC[1-2] reboot"
- ['R SSC[1-2] C !!!ready!!!']
- - "SSC SSC[1-2] ble -R"
- ["R SSC[1-2] C +BLE:OK"]
- - "SSC SSC1 blesmp -B -z getnum"
- ['P SSC1 C +BLESMP:GetBondNum,4']
- - "SSC SSC2 blesmp -B -z getnum"
- ['P SSC2 C +BLESMP:GetBondNum,1']
- - "SSC SSC2 blesmp -B -z remove -r <dut1_bt_mac>"
- ['P SSC2 RE "\+BLESMP:RemoveBond,Success,%%s"%%(<dut1_bt_mac>)']
- ID: BTSTK_SMP_08004
<<: *SMP_CASE
test point 2: BLE SMP bond item management test
@ -2304,3 +2318,336 @@ test cases:
- ""
- - "SSC SSC1 blesmp -B -z remove -r <dut2_bt_mac>"
- ['P SSC1 C +BLESMP:RemoveBond,Fail']
- ID: BTSTK_SMP_08005
<<: *SMP_CASE
test point 2: BLE SMP remove bond
summary: BLE SMP bond 15/16 devices and get list
steps: |
1. DUT2 set AuthReqMode and RspKey
2. DUT2 set static random address
3. DUT1 and DUT2 do pairing
4. loop step 2 and step3 16 times
5. get bond list and bond num
6. DUT2 set static random address
7. DUT1 and DUT2 do pairing
8. get bond list and bond num
expected result: |
1. Succeed
2. Succeed
3. Succeed
4. succeed
5. succeed
6. succeed
7. succeed
8. succeed
cmd set:
- ""
- - "SSC SSC[1-2] blesmp -S -z AuthReqMode -v 0x01"
- ['P SSC[1-2] C +BLESMP:OK']
- - "SSC SSC[1-2] blesmp -S -z IOCAP -v 0x03"
- ['P SSC[1-2] C +BLESMP:OK']
- - "SSC SSC[1-2] blesmp -S -z RspKey -v 0x03"
- ['P SSC[1-2] C +BLESMP:OK']
- - LOOP 15 7 "range(0,15)" "range(0,15)" "range(0,15)"
- ""
- - "SSC SSC2 bleadv -D -z stop"
- ['R SSC2 C +BLEADV:Stop,OK']
- - "SSC SSC2 ble -S -z randAddr -a c0:9b:0e:36:6d:7{%x} -r 1"
- ["R SSC2 C +BLECONN:SetRandAddr,OK"]
- - "SSC SSC2 bleadv -D -z start -o 1"
- ['R SSC2 C +BLEADV:Start,OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a c0:9b:0e:36:6d:7{%x} -r 1"
- ['P SSC1 C +BLE:GattcConnect,OK', 'P SSC2 C +BLE:GattsConnect']
- - "SSC SSC2 blesmp -E -r <dut1_bt_mac> -z Enc"
- ['P SSC1 C +BLESMP:SecReq']
- - "SSC SSC1 blesmp -R -a 1 -r c0:9b:0e:36:6d:7{%x}"
- ['P SSC1 C +BLESMP:AuthComplete,Success,0','P SSC2 C +BLESMP:AuthComplete,Success,0']
- - "SSC SSC1 bleconn -D -z all"
- ['P SSC1 C +BLE:CLOSE', 'P SSC2 C +BLE:GattsDisconnect']
- - "SSC SSC1 blesmp -B -z getlist -n 16"
- ['P SSC1 C +BLESMP:GetBondList,OK,15']
- - "SSC SSC2 ble -S -z randAddr -a c1:0a:d3:25:7a:cf -r 1"
- ["R SSC2 C +BLECONN:SetRandAddr,OK"]
- - "SSC SSC2 bleadv -D -z stop"
- ['R SSC2 C +BLEADV:Stop,OK']
- - "SSC SSC2 bleadv -D -z start -o 1"
- ['R SSC2 C +BLEADV:Start,OK']
- - "SSC SSC1 bleconn -C -p 0x10 -a c1:0a:d3:25:7a:cf -r 1"
- ['P SSC1 C +BLE:GattcConnect,OK', 'P SSC2 C +BLE:GattsConnect']
- - "SSC SSC2 blesmp -E -r <dut1_bt_mac> -z Enc"
- ['P SSC1 C +BLESMP:SecReq']
- - "SSC SSC1 blesmp -R -a 1 -r c1:0a:d3:25:7a:cf"
- ['P SSC1 C +BLESMP:AuthComplete,Success,0','P SSC2 C +BLESMP:AuthComplete,Success,0']
- - "SSC SSC1 blesmp -B -z getlist -n 16"
- ['P SSC1 C +BLESMP:GetBondList,OK,15']
- ID: BTSTK_SMP_50001
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT read char performance test after just work pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do read char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "read"
- ""
- - pair_op = "just_work_pair"
- ""
- - op_char = "0xC301"
- ""
- ID: BTSTK_SMP_50002
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT read char performance test after numberic comparision pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do read char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "read"
- ""
- - pair_op = "numberic_comparision_pair"
- ""
- - op_char = "0xC301"
- ""
- ID: BTSTK_SMP_50003
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT write char performance test after just work pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "write"
- ""
- - op_char = "0xC304"
- ""
- - pair_op = "just_work_pair"
- ""
- - op_len = 490
- ""
- ID: BTSTK_SMP_50004
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT write char performance test after numberic comparision pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do write char for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "write"
- ""
- - op_char = "0xC304"
- ""
- - pair_op = "numberic_comparision_pair"
- ""
- - op_len = 490
- ""
- ID: BTSTK_SMP_50005
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT notify performance test after just work pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do notify for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "notify"
- ""
- - op_char = "0xC305"
- ""
- - pair_op = "just_work_pair"
- ""
- - op_len = 490
- ""
- ID: BTSTK_SMP_50006
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT notify performance test after numberic comparision pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do notify for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "notify"
- ""
- - op_char = "0xC305"
- ""
- - pair_op = "numberic_comparision_pair"
- ""
- - op_len = 490
- ""
- ID: BTSTK_SMP_50007
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT indicate performance test after just work pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do notify for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "indicate"
- ""
- - pair_op = "just_work_pair"
- ""
- - op_char = "0xC306"
- ""
- - op_len = 490
- ""
- ID: BTSTK_SMP_50008
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP GATT performance test
summary: GATT indicate performance test after numberic comparision pair
Test App: SSC_BLE_PERF
steps: |
1. update connection parameter
2. do primary service discovery
3. do notify for some time
expected result: |
1. succeed
2. succeed
3. calculate throughput
execution time: 2
cmd set:
- "BLEStress/BLESMPGATTPerformance"
- - test_time = 420
- ""
- - mtu = 512
- ""
- - gatt_op = "indicate"
- ""
- - pair_op = "numberic_comparision_pair"
- ""
- - op_char = "0xC306"
- ""
- - op_len = 490
- ""
- ID: BTSTK_SMP_51001
<<: *SMP_CASE
category: Performance
test point 1: performance + stress
test point 2: BLE SMP performance test
summary: BLE SMP Connect and disconnect performance test
steps: |
1. DUT2 set AuthReqMode and RspKey
2. DUT1 disconnect with DUT2
3. DUT2 start advertising
4. DUT1 connect to DUT2
5. do service discovery
6. loop step 1-4
7. check connection fail ratio and average conn time
expected result: |
1. succeed
2. succeed
3. succeed
4. succeed
5. succeed
6. succeed
7. meet pass standard
execution time: 6
version: v1 (2017-05-19)
CI ready: 'No'
cmd set:
- "BLEStress/BLESMPConnPerformance"
- - "test_time = 420"
- ""
- - "average_conn_time = 3"
- ""
- - "fail_ratio = 0.01"
- ""
- - "fail_timeout = 10"
- ""

View file

@ -21,7 +21,7 @@ test cases:
steps: 系统重启
sub module: Misc
summary: test reboot function
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: sw reboot
version: v1 (2016-8-15)
@ -49,7 +49,7 @@ test cases:
steps: 查询空闲ram
sub module: Misc
summary: get heap size test
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: 'get heap size '
version: v1 (2016-8-15)

View file

@ -38,7 +38,7 @@ test cases:
打开DHCP OK\n5.查询到sta ip \n6.target1 连接AP ok\n7.查询到sta ip 为target_ip"
sub module: DHCP
summary: dhcp client function test
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: DHCP client function test
version: v2 (2016-10-19)
@ -90,7 +90,7 @@ test cases:
7.target1 查询 DHCP 状态
sub module: DHCP
summary: dhcp status query
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: DHCP client function test
version: v1 (2016-8-15)
@ -136,7 +136,7 @@ test cases:
打开DHCP ok"
sub module: DHCP
summary: server dhcp lease test
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -185,7 +185,7 @@ test cases:
4. Loop step3
sub module: DHCP
summary: dhcp server ip pool
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -242,7 +242,7 @@ test cases:
4. Loop step3 twice
sub module: DHCP
summary: dhcp server ip pool empty
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -306,7 +306,7 @@ test cases:
8. target2 change mac and connect to target1
sub module: DHCP
summary: dhcp server timeout test
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -347,7 +347,7 @@ test cases:
3. disable DHCP server, do config and enable
sub module: DHCP
summary: disconnect STA if config dhcp server
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -398,7 +398,7 @@ test cases:
5. change to first mac, connect to softap
sub module: DHCP
summary: dhcp server assign same IP to same MAC when it's not released
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -455,7 +455,7 @@ test cases:
6. target2 change mac and connect to target1
sub module: DHCP
summary: dhcp server prefer assign released IP to new client
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -516,7 +516,7 @@ test cases:
7. target2 change mac and connect to target1
sub module: DHCP
summary: dhcp server prefer assign released IP to new client
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -568,7 +568,7 @@ test cases:
5. softap list connected station
sub module: DHCP
summary: dhcp server reconfig and new client able to get first IP in pool
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -624,7 +624,7 @@ test cases:
7. softap list connected station
sub module: DHCP
summary: dhcp server reconfig and new client able to get first IP in pool
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -674,7 +674,7 @@ test cases:
5. softap list connected station
sub module: DHCP
summary: dhcp server reconfig, old client and new client able to get IP
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -723,7 +723,7 @@ test cases:
sub module: DHCP
summary: dhcp server reconfig, old client able to get IP (discover with requested
IP)
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -749,6 +749,8 @@ test cases:
- - R SSC1 C +DHCP:LEASE,OK
- - SSC SSC1 dhcp -S -o 2
- - R SSC1 C +DHCP:AP,OK
- - WIFI <pc_wifi_nic> CONN <random_string> <random_string> 192.168.4.2
- - R PC_COM NC ERROR C +WIFICONN:OK
- - SSC SSC2 sta -C -s <random_string> -p <random_string>
- - R SSC2 C +JAP:CONNECTED
- - DELAY 30
@ -773,7 +775,7 @@ test cases:
5. softap list connected station
sub module: DHCP
summary: dhcp server reconfig, old client able to renew IP (direct send request)
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: DHCP server function test
version: v1 (2016-8-15)
@ -812,7 +814,7 @@ test cases:
打开DHCP OK\n5.target2 jap target 1,ok"
sub module: DHCP
summary: dhcp server function test
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: DHCP server function test
version: v2 (2016-10-19)
@ -859,7 +861,7 @@ test cases:
6.target1 jap AP
sub module: DHCP
summary: sta dhcp static ip interaction
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: interaction
test point 2: static IP and DHCP interaction test
version: v2 (2016-10-19)
@ -914,7 +916,7 @@ test cases:
设置正确的地址池\n9.target2 连接target1 "
sub module: DHCP
summary: ap dhcp static ip interaction
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: interaction
test point 2: static IP and DHCP interaction test
version: v1 (2016-8-15)

View file

@ -18,7 +18,7 @@ test cases:
initial condition: STAM2
level: Integration
module: TCPIP
steps: 1. get host name "espressif.cn"
steps: 1. get host name "gbot.espressif.cn"
sub module: DNS
summary: get host by name test
test environment: SSC_T1_2
@ -54,7 +54,7 @@ test cases:
level: Integration
module: TCPIP
steps: |-
1. get host name "espressif.cn"
1. get host name "gbot.espressif.cn"
2. connect, send, recv
sub module: DNS
summary: TCP connect to gbot.espressif.cn
@ -147,3 +147,301 @@ test cases:
test point 1: abnormal/special use
test point 2: use special DNS server config
version: v1 (2016-8-15)
- CI ready: 'No'
ID: TCPIP_DNS_0301
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- DNSTest/DNSTest
- - test_mode = "fallback_main_backup_dns_all_error"
- ['']
- - fallback_dns_option = "error"
- ['']
- - test_option = "main_backup_error"
- ['']
- - test_count = 20
- [dummy]
- - fallback_dns = "1.1.1.1"
- ['']
- - website_dns = "www.baidu.com"
- ['']
execution time: 0.3
expected result: |-
2.mode set ok
3.connect ap sucess
4.set fallback dns ok
5.get dns ip fail
initial condition: None
level: Integration
module: TCPIP
steps: |-
1.AP main,backup DNS all error
2.set SSC1 to sta mode
3.SSC1 connect to ap
4.set SSC1 fallback DNS
5.SSC1 get website dns IP
sub module: DNS
summary: DNS fallback main backup DNS all error test
test environment: SSC_T1_DNS
test point 1: stress + function
test point 2: DNS stress test
version: v2 (2016-10-23)
- CI ready: 'No'
ID: TCPIP_DNS_0302
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- DNSTest/DNSTest
- - test_mode = "fallback_dns_error_mian_backup_dns_right"
- ['']
- - fallback_dns_option = "error"
- ['']
- - test_option = "main_backup_right"
- ['']
- - test_count = 20
- [dummy]
- - fallback_dns = "2.2.2.2"
- ['']
- - website_dns = "www.baidu.com"
- ['']
execution time: 0.3
expected result: |-
2.mode set ok
3.connect ap sucess
4.set fallback dns ok
5.get dns ip ok
initial condition: None
level: Integration
module: TCPIP
steps: |-
1.AP main,backup DNS all right
2.set SSC1 to sta mode
3.SSC1 connect to ap
4.set SSC1 fallback DNS
5.SSC1 get website dns IP
sub module: DNS
summary: DNS fallback DNS error main backup DNS right test
test environment: SSC_T1_DNS
test point 1: stress + function
test point 2: DNS stress test
version: v2 (2016-10-23)
- CI ready: 'No'
ID: TCPIP_DNS_0303
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- DNSTest/DNSTest
- - test_mode = "fallback_main_dns_error_backup_dns_right"
- ['']
- - fallback_dns_option = "error"
- ['']
- - test_option = "backup_right"
- ['']
- - test_count = 20
- [dummy]
- - fallback_dns = "1.1.1.1"
- ['']
- - website_dns = "www.baidu.com"
- ['']
execution time: 0.3
expected result: |-
2.mode set ok
3.connect ap sucess
4.set fallback dns ok
5.get dns ip ok
initial condition: None
level: Integration
module: TCPIP
steps: |-
1.AP main DNS error,backup DNS right
2.SSC1 set as sta mode
3.SSC1 connect to ap
4.set SSC1 fallback DNS
5.SSC1 get website dns IP
sub module: DNS
summary: DNS fallback main DNS error backup DNS right test
test environment: SSC_T1_DNS
test point 1: stress + function
test point 2: DNS stress test
version: v2 (2016-10-23)
- CI ready: 'No'
ID: TCPIP_DNS_0304
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- DNSTest/DNSTest
- - test_mode = "fallback_main_backup_dns_all_right"
- ['']
- - fallback_dns_option = "right"
- ['']
- - test_option = "main_backup_right"
- ['']
- - test_count = 20
- [dummy]
- - fallback_dns = "208.67.222.222"
- ['']
- - website_dns = "www.baidu.com"
- ['']
execution time: 0.3
expected result: |-
2.mode set ok
3.connect ap sucess
4.set fallback dns ok
5.get dns IP ok
initial condition: None
level: Integration
module: TCPIP
steps: |-
1.AP main ,backup DNS right
2.SSC1 set as sta mode
3.SSC1 connect to ap
4.set SSC1 fallback DNS
5.SSC1 get website dns IP
sub module: DNS
summary: DNS fallback main backup DNS all right test
test environment: SSC_T1_DNS
test point 1: stress + function
test point 2: DNS stress test
version: v2 (2016-10-23)
- CI ready: 'No'
ID: TCPIP_DNS_0305
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- DNSTest/DNSTest
- - test_mode = "fallback_dns_right_main_backup_error"
- ['']
- - fallback_dns_set = "right"
- ['']
- - fallback_dns_option = "right"
- ['']
- - test_option = "main_backup_error"
- ['']
- - test_count = 20
- [dummy]
- - fallback_dns = "208.67.222.222"
- ['']
- - website_dns = "www.baidu.com"
- ['']
execution time: 0.3
expected result: |-
2.mode set ok
3.connect ap sucess
4.set fallback dns ok
5.get dns IP ok
initial condition: None
level: Integration
module: TCPIP
steps: |-
1.AP main ,backup DNS all error
2.SSC1 set as mode
3.SSC1 connect to ap
4.set SSC1 fallback DNS
5.SSC1 get website dns IP
sub module: DNS
summary: DNS fallback DNS right main backup error test
test environment: SSC_T1_DNS
test point 1: stress + function
test point 2: DNS stress test
version: v2 (2016-10-23)
- CI ready: 'No'
ID: TCPIP_DNS_0306
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- DNSTest/DNSTest
- - test_mode = "dns_dhcp_option"
- ['']
- - test_count = 20
- [dummy]
- - fallback_dns = "208.67.222.222"
- ['']
- - website_dns = "www.baidu.com"
- ['']
execution time: 0.3
expected result: |-
1.ap set ok
2.set sta mode ok
3.jap ok
4.disable dhcp ok
5.set static ip addr suc
6.set fallback dns suc
7.get dns ip suc
8.dhcp start suc
9.get dns ip ok
11.jap ok
12.get dns ip ok
initial condition: None
level: Integration
module: TCPIP
steps: |-
1.AP main ,backup DNS all right
2.set SSC1 to sta mode
3.SSC1 connect to ap
4.SSC1 disable dhcp
5.SSC1 set static ip addr
6.SSC1 set fallback dns
7.SSC1 get website dns IP
8.SSC1 start dhcp
9.SSC1 get website dns IP
10.SSC1 disconnect with ap
11.SSC1 reconnet ap
12.SSC1 get website dns IP
sub module: DNS
summary: DNS DHCP option test
test environment: SSC_T1_DNS
test point 1: stress + function
test point 2: DNS stress test
version: v2 (2016-10-23)
- CI ready: 'No'
ID: TCPIP_DNS_0307
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- DNSTest/DNSTest
- - test_mode = "softap_dns_test"
- ['']
- - test_count = 20
- [dummy]
- - main_dns = "208.67.222.222"
- ['']
execution time: 0.3
expected result: |-
1.set mode ok
2.set mode ok
3.sta connect softap suc
4.disable dhcp ok
5.set dns server suc
6.set main dns suc
7.SSC2 main dns must the same as SSC1
initial condition: None
level: Integration
module: TCPIP
steps: |-
1.SSC1 set as softap
2.SSC2 set as sta
3.SSC2 connected softap
4.SSC1 disable dhcp
5.SSC1 dhcp action dns server
6.SSC1 set main dns
7.check SSC2 main dns server
sub module: DNS
summary: DNS softap DNS test
test environment: SSC_T2_1
test point 1: stress + function
test point 2: DNS stress test
version: v2 (2016-10-23)

View file

@ -27,7 +27,7 @@ test cases:
2.ping -i <pc_ip> -c 2
sub module: ICMP
summary: ping function test
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: ping function test
version: v1 (2016-8-15)

View file

@ -39,7 +39,7 @@ test cases:
4. join group with wrong host addr and wrong multicast addr
sub module: IGMP
summary: station IGMP join group address check
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
@ -83,7 +83,7 @@ test cases:
5. leave group with correct host addr and correct multicast addr
sub module: IGMP
summary: station IGMP leave group address check
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
@ -127,7 +127,7 @@ test cases:
4. join group with wrong host addr and wrong multicast addr
sub module: IGMP
summary: softAP IGMP join group address check
test environment: SSC_T1_1
test environment: SSC_T1_8
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
@ -171,7 +171,7 @@ test cases:
5. leave group with correct host addr and correct multicast addr
sub module: IGMP
summary: softAP IGMP leave group address check
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
@ -180,9 +180,8 @@ test cases:
SDK: |-
8266_NonOS
8266_RTOS
ESP32_IDF
Test App: SSC
allow fail: '1/2'
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
@ -211,7 +210,7 @@ test cases:
3. PC send UDP packet to multicast addr
sub module: IGMP
summary: station IGMP recv packets
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)
@ -220,9 +219,8 @@ test cases:
SDK: |-
8266_NonOS
8266_RTOS
ESP32_IDF
Test App: SSC
allow fail: '1/2'
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
@ -257,7 +255,7 @@ test cases:
4. target2 send to multicast addr
sub module: IGMP
summary: station send multicast packets
test environment: SSC_T2_1
test environment: SSC_T2_4
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)
@ -266,7 +264,6 @@ test cases:
SDK: |-
8266_NonOS
8266_RTOS
ESP32_IDF
Test App: SSC
allow fail: ''
auto test: 'Yes'
@ -297,7 +294,7 @@ test cases:
3. PC send UDP packet to multicast addr
sub module: IGMP
summary: softAP IGMP recv packets
test environment: SSC_T1_1
test environment: SSC_T1_8
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)
@ -306,7 +303,6 @@ test cases:
SDK: |-
8266_NonOS
8266_RTOS
ESP32_IDF
Test App: SSC
allow fail: ''
auto test: 'Yes'
@ -341,7 +337,383 @@ test cases:
4. target2 send to multicast addr
sub module: IGMP
summary: softAP send multicast packets
test environment: SSC_T2_1
test environment: SSC_T2_4
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0101
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 soc -B -t UDP -p <test_udp_port1>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -J -s <sock1> -m 223.1.1.1
- - R SSC1 C +IGMP:ERROR
- - SSC SSC1 soc -J -s <sock1> -m 240.1.1.1
- - R SSC1 C +IGMP:ERROR
execution time: 0.0
expected result: |
1. OK
2. OK
3. OK
4. ERROR
5. ERROR
initial condition: STAM2
level: Integration
module: TCPIP
steps: |
1. create UDP socket
2. join group with correct multicast addr
3. leave group with correct multicast addr
4. join group with wrong multicast addr
5. join group with wrong multicast addr
sub module: IGMP
summary: station IGMP join group address check
test environment: SSC_T1_6
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0102
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 soc -B -t UDP -p <test_udp_port1>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -B -t UDP -p <random_port>
- - R SSC1 A <sock2>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock2> -m 224.1.1.2
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -G -s <sock2> -m 224.1.1.1
- - R SSC1 C +IGMP:ERROR
execution time: 0.0
expected result: |
1. OK
2. OK
3. OK
4. OK
5. OK
6. ERROR
initial condition: STAM2
level: Integration
module: TCPIP
steps: |
1. create UDP socket
2. join group with correct multicast addr
3. leave group with correct multicast addr
4. create UDP socket
5. join group with correct multicast addr
6. leave group with wrong multicast addr
sub module: IGMP
summary: station IGMP leave group address check
test environment: SSC_T1_5
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0103
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 soc -B -t UDP -p <test_udp_port1>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -J -s <sock1> -m 223.1.1.1
- - R SSC1 C +IGMP:ERROR
- - SSC SSC1 soc -J -s <sock1> -m 240.1.1.1
- - R SSC1 C +IGMP:ERROR
execution time: 0.0
expected result: |
1. OK
2. OK
3. OK
4. ERROR
5. ERROR
initial condition: APM2
level: Integration
module: TCPIP
steps: |
1. create UDP socket
2. join group with correct multicast addr
3. leave group with correct multicast addr
4. join group with wrong multicast addr
5. join group with wrong multicast addr
sub module: IGMP
summary: softAP IGMP join group address check
test environment: SSC_T1_8
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0104
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 soc -B -t UDP -p <test_udp_port1>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -B -t UDP -p <random_port>
- - R SSC1 A <sock2>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock2> -m 224.1.1.2
- - R SSC1 C +IGMP:OK
- - SSC SSC1 soc -G -s <sock2> -m 224.1.1.1
- - R SSC1 C +IGMP:ERROR
execution time: 0.0
expected result: |
1. OK
2. OK
3. OK
4. OK
5. OK
6. ERROR
initial condition: APM2
level: Integration
module: TCPIP
steps: |
1. create UDP socket
2. join group with correct multicast addr
3. leave group with correct multicast addr
4. create UDP socket
5. join group with correct multicast addr
6. leave group with wrong multicast addr
sub module: IGMP
summary: softAP IGMP leave group address check
test environment: SSC_T1_7
test point 1: basic function
test point 2: IGMP API parameter check
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0201
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: '1/5'
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 soc -B -t UDP -p <test_udp_port2>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SOC SOC1 BIND <test_udp_port2>
- - R SOC_COM L OK
- - SOC SOC1 SENDTO 1 <test_udp_port2> 224.1.1.1
- - R SSC1 SL <sock1>+1
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SOC SOC1 SENDTO 1 <test_udp_port2> 224.1.1.1
- - R SSC1 NC +RECVFROM
execution time: 0.0
expected result: |
1. OK
2. OK
3. OK
4. able to recv packet
5. OK
6. not able to recv packet
initial condition: STAM2
level: Integration
module: TCPIP
steps: |
1. create UDP socket
2. join group with correct multicast addr
3. PC上 SOC1 UDP 传输bing <test_udp_port2> <pc_ip>
4. PC send UDP packet to multicast addr
5. leave group with correct multicast addr
6. PC send UDP packet to multicast addr
sub module: IGMP
summary: station IGMP recv packets
test environment: SSC_T1_6
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0202
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: '1/5'
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC2 op -S -o 1
- - R SSC2 C +MODE:OK
- - SSC SSC2 sta -C -s <ap_ssid> -p <ap_password>
- - R SSC2 C +JAP:CONNECTED
- - SSC SSC2 soc -T
- - R SSC2 C +CLOSEALL
- - SSC SSC1 soc -B -t UDP -p <test_udp_port1>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC2 soc -B -t UDP -p <random_port>
- - R SSC2 A <sock2>:\+BIND:(\d+),OK
- - SSC SSC2 soc -S -s <sock2> -i 224.1.1.1 -p <test_udp_port1> -l 10
- - R SSC1 SL <sock1>+1
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC2 soc -S -s <sock2> -i 224.1.1.1 -p <test_udp_port1> -l 10
- - R SSC1 NC +RECVFROM
- - SSC SSC2 soc -T -s <sock2>
- - R SSC2 RE CLOSE:\d+,OK
execution time: 0.0
expected result: |
1. OK
2. target2 connect succeed
3. CLOSEALL
4. OK
5. OK
6. OK
7. able to recv packet
8. OK
9. not able to recv packet
10. OK
initial condition: STAM2
level: Integration
module: TCPIP
steps: |
1. target2 set to sta mode
2. target2 join AP
3. target2 close socket
4. target1 create UDP socket
5. target1 join group using multicast addr
6. target2 create UDP socket
7. target2 send to multicast addr
8. target1 leave group with correct multicast addr
9. target2 send to multicast addr
10. target2 close socket
sub module: IGMP
summary: station send multicast packets
test environment: SSC_T2_4
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0203
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 soc -B -t UDP -p <test_udp_port1>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SOC SOC1 BIND <test_udp_port1> <pc_ip_wifi>
- - R SOC_COM L OK
- - SOC SOC1 SENDTO 1 <test_udp_port1> 224.1.1.1
- - R SSC1 SL <sock1>+1
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SOC SOC1 SENDTO 1 <test_udp_port1> 224.1.1.1
- - R SSC1 NC +RECVFROM
execution time: 0.0
expected result: |
1. OK
2. OK
3. OK
4. able to recv packet
5. OK
6. not able to recv packet
initial condition: APM2
level: Integration
module: TCPIP
steps: |
1. create UDP socket
2. join group using multicast addr
3. PC上 SOC1 UDP 传输bing <test_udp_port1> <pc_ip_wifi>
4. PC send UDP packet to multicast addr
5. leave group with correct multicast addr
6. PC send UDP packet to multicast addr
sub module: IGMP
summary: softAP IGMP recv packets
test environment: SSC_T1_8
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_IGMP_0204
SDK: 'ESP32_IDF'
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC2 sta -C -s <target_ssid> -p <target_password>
- - R SSC2 C +JAP:CONNECTED
- - SSC SSC1 soc -B -t UDP -p <test_udp_port1>
- - R SSC1 A <sock1>:\+BIND:(\d+),OK
- - SSC SSC1 soc -J -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC2 soc -B -t UDP -p <random_port>
- - R SSC2 A <sock2>:\+BIND:(\d+),OK
- - SSC SSC2 soc -S -s <sock2> -i 224.1.1.1 -p <test_udp_port1> -l 10
- - R SSC1 SL <sock1>+1
- - SSC SSC1 soc -G -s <sock1> -m 224.1.1.1
- - R SSC1 C +IGMP:OK
- - SSC SSC2 soc -S -s <sock2> -i 224.1.1.1 -p <test_udp_port1> -l 10
- - R SSC1 NC +RECVFROM
- - SSC SSC2 soc -T -s <sock2>
- - R SSC2 RE CLOSE:\d+,OK
execution time: 0.0
expected result: |
1. target2 connect succeed
2. OK
3. OK
4. OK
5. target1 able to recv packet
6. OK
7. target1 not able to recv packet
8. OK
initial condition: APM2
level: Integration
module: TCPIP
steps: |
1. target2 join AP
2. target1 create UDP socket
3. target1 join group using multicast addr
4. target2 create UDP socket
5. target2 send to multicast addr
6. target1 leave group with correct multicast addr
7. target2 send to multicast addr
8. target2 close socket
sub module: IGMP
summary: softAP send multicast packets
test environment: SSC_T2_4
test point 1: basic function
test point 2: IGMP send/recv test
version: v1 (2016-8-15)

View file

@ -35,7 +35,7 @@ test cases:
1\n5.target1 设置sta ip 192.168.123.123\n6.target1 查询 当前sta ip "
sub module: IP
summary: sta set and query static ip test
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: set and query static IP
version: v1 (2016-8-15)
@ -79,7 +79,7 @@ test cases:
ip 为target_ap_ip"
sub module: IP
summary: ap set and query static ip test
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: set and query static IP
version: v1 (2016-8-15)

View file

@ -44,7 +44,7 @@ test cases:
6.target1上使用步骤2创建的socket去连接 PC的ip远端端口不存在。
sub module: TCP
summary: STA mode, connect test. use different ip, port
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -86,7 +86,7 @@ test cases:
4.PC tcp 连接到不存在的port ,<target_ip>
sub module: TCP
summary: STA mode, server listen test. use different kinds of port
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -133,14 +133,14 @@ test cases:
steps: |
1. PC上建立TCP 监听 test_tcp_port1
2.target1上创建TCP socket
3.target1上使用步骤2创建的socket去连接PC的iptest_tcp_port1
3.target1上使用步骤2创建的socket去连接 PC的iptest_tcp_port1
4.PC与target1 创建好TCP 连接有ACCEPT
5.PC send 5 bytes to 8266
6.8266 send 5 bytes to PC
7.8266 send 1460 to PC.
sub module: TCP
summary: STA mode, send/recv basic test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -204,7 +204,7 @@ test cases:
10.target1 shutdown socket3 R
sub module: TCP
summary: STA mode, shutdown basic test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -278,7 +278,7 @@ test cases:
socket1\n15.target1关闭socket1"
sub module: TCP
summary: STA mode, close for different types of TCP sockets test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -346,7 +346,7 @@ test cases:
11.target1上使用步骤10创建的socket5去连接 PC的iptest_tcp_port1,PC有ACCEPT
sub module: TCP
summary: STA mode, create max TCP sockets test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -395,7 +395,7 @@ test cases:
\ "
sub module: TCP
summary: STA mode, accept max TCP client by server test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -459,7 +459,7 @@ test cases:
11.target1 abort socket1
sub module: TCP
summary: STA mode, espconn abort test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -508,7 +508,7 @@ test cases:
6.target1上使用步骤2创建的socket去连接 PC的ip远端端口不存在。
sub module: TCP
summary: AP mode, connect test. use different ip, port
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -550,7 +550,7 @@ test cases:
4.PC tcp 连接到不存在的port ,<target_ip>
sub module: TCP
summary: AP mode, server listen test. use different kinds of port
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -595,7 +595,7 @@ test cases:
level: Integration
module: TCPIP
steps: |
1. PC上建立TCP 监听 test_tcp_port1
1.PC上建立TCP 监听 test_tcp_port1
2.target1上创建TCP socket
3.target1上使用步骤2创建的socket去连接PC的iptest_tcp_port1
4.PC与target1 创建好TCP 连接有ACCEPT
@ -604,7 +604,7 @@ test cases:
7.8266 send 100 * 1460 to PC.
sub module: TCP
summary: AP mode, send/recv basic test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -668,7 +668,7 @@ test cases:
10.target1 shutdown socket3 R
sub module: TCP
summary: AP mode, shutdown basic test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -742,7 +742,7 @@ test cases:
socket1\n15.target1关闭socket1"
sub module: TCP
summary: AP mode, close for different types of TCP sockets test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -810,7 +810,7 @@ test cases:
11.target1上使用步骤10创建的socket5去连接 PC的iptest_tcp_port1,PC有ACCEPT
sub module: TCP
summary: AP mode, create max TCP sockets test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -859,7 +859,7 @@ test cases:
\ "
sub module: TCP
summary: AP mode, accept max TCP client by server test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -931,7 +931,7 @@ test cases:
12.target1上使用步骤2创建的socket去连接 PC的ip<test_tcp_port1>
sub module: TCP
summary: STA mode, connect test. use socket in state that can't connect
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -991,7 +991,7 @@ test cases:
9.target1上使用不存在socket,创建TCP 监听
sub module: TCP
summary: STA mode, server listen test. use socket in state that can't listen
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -1051,7 +1051,7 @@ test cases:
9.target1上不指定socket往上发送数据
sub module: TCP
summary: send test. use socket in state that can't send
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -1101,8 +1101,8 @@ test cases:
6.PC send 100 * 1460 data to target,
7.在target上开始recv
sub module: TCP
summary: STA mode, recv buffer test
test environment: SSC_T1_1
summary: STA mode, TCP recv buffer test
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v2 (2016-10-19)
@ -1138,7 +1138,6 @@ test cases:
- - R SSC1 A <sock4>:ACCEPT:(\d+),\d+,.+,\d+
- - SSC SSC1 soc -I
- - P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(<sock1>,<target_ip>,<pc_ip>,<test_tcp_port1>)
- P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%(<sock2>)
- P SSC1 RE "SOCINFO:%%s,82,.+,%%d"%%(<sock3>,<random_port>)
- P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(<sock4>,<target_ip>,<random_port>,<pc_ip>)
execution time: 0.0
@ -1166,8 +1165,8 @@ test cases:
CONNECT<random_port>,<target_ip> ,tcp 连接创建成功创建socket4 \n10.target1 查询the socket
information"
sub module: TCP
summary: STA mode, get active socket info test
test environment: SSC_T1_1
summary: STA mode, TCP get active socket info test
test environment: SSC_T1_6
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -1239,7 +1238,7 @@ test cases:
12.target1上使用步骤2创建的socket去连接 PC的ip<test_tcp_port1>
sub module: TCP
summary: AP mode, connect test. use socket in state that can't connect
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -1299,7 +1298,7 @@ test cases:
9.target1上使用不存在socket,创建TCP 监听
sub module: TCP
summary: AP mode, server listen test. use socket in state that can't listen
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -1348,8 +1347,8 @@ test cases:
6.PC send 100 * 1460 data to 8266,
7.target重新调用recv
sub module: TCP
summary: AP mode, recv buffer test
test environment: SSC_T1_1
summary: AP mode, TCP recv buffer test
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v2 (2016-10-19)
@ -1385,7 +1384,6 @@ test cases:
- - R SSC1 A <sock4>:ACCEPT:(\d+),\d+,.+,\d+
- - SSC SSC1 soc -I
- - P SSC1 RE "SOCINFO:%%s,2,%%s,\d+,%%s,%%d"%%(<sock1>,<target_ap_ip>,<pc_ip_wifi>,<test_tcp_port1>)
- P SSC1 RE "SOCINFO:%%s,2,.+,\d+,.+,\d+"%%(<sock2>)
- P SSC1 RE "SOCINFO:%%s,82,.+,%%d"%%(<sock3>,<random_port>)
- P SSC1 RE "SOCINFO:%%s,2,%%s,%%d,%%s,\d+"%%(<sock4>,<target_ap_ip>,<random_port>,<pc_ip_wifi>)
execution time: 0.0
@ -1413,8 +1411,8 @@ test cases:
CONNECT<random_port>,<target_ip> ,tcp 连接创建成功创建socket4 \n10.target1 查询the socket
information"
sub module: TCP
summary: AP mode, get active socket info test
test environment: SSC_T1_1
summary: AP mode, TCP get active socket info test
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -1478,7 +1476,7 @@ test cases:
11.target1 abort socket1
sub module: TCP
summary: AP mode, espconn abort test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use TCP SAP (socket/espconn API) in different state
version: v1 (2016-8-15)
@ -1501,7 +1499,7 @@ test cases:
steps: 1.lev -N -t GET
sub module: TCP
summary: STA mode, max connections number query
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1542,7 +1540,7 @@ test cases:
5.lev -N -t SET -n 8
sub module: TCP
summary: STA mode, max connections number set
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1613,7 +1611,7 @@ test cases:
10.target1上使用步骤5创建的socket4去连接 pc_ip_wifi的iptest_tcp_port1,未连接成功
sub module: TCP
summary: STA mode, max connections fucntion verify
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1674,7 +1672,7 @@ test cases:
9.target1上lev -N -t SET -n 8
sub module: TCP
summary: STA mode, max connections set interact with TCP connect and send
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1716,7 +1714,7 @@ test cases:
5.target1上lev -A -s <sock1> -t SET -n 4
sub module: TCP
summary: STA mode, max TCP connection allowed by server test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1761,7 +1759,7 @@ test cases:
-K -s <sock1> -t GET \n6.lev -K -s <sock1> -t SET -i 30 -d 3 -c 2\n7.等待30s"
sub module: TCP
summary: STA mode, keep alive test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1820,7 +1818,7 @@ test cases:
-K -s <sock1> -t GET \n6.lev -K -s <sock1> -t SET -i 30 -d 3 -c 2\n7.PC往8266发送数据\n8.8266往PC上发送数据\n9.PC往8266发送146000数据\n10.8266往PC上发送1460*100数据\n11.等待30s"
sub module: TCP
summary: STA mode, keep alive interact with TCP send
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1843,7 +1841,7 @@ test cases:
steps: 1.lev -N -t GET
sub module: TCP
summary: AP mode, max connections number query
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1884,7 +1882,7 @@ test cases:
5.lev -N -t SET -n 8
sub module: TCP
summary: AP mode, max connections number set
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -1955,7 +1953,7 @@ test cases:
10.target1上使用步骤5创建的socket4去连接 pc_ip_wifi的iptest_tcp_port1,未连接成功
sub module: TCP
summary: AP mode, max connections fucntion verify
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -2016,7 +2014,7 @@ test cases:
9.target1上lev -N -t SET -n 8
sub module: TCP
summary: AP mode, max connections set interact with TCP connect and send
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -2059,7 +2057,7 @@ test cases:
5.target1上lev -A -s <sock1> -t SET -n 4
sub module: TCP
summary: AP mode, max TCP connection allowed by server test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -2105,7 +2103,7 @@ test cases:
-K -s <sock1> -t GET \n6.lev -K -s <sock1> -t SET -i 30 -d 3 -c 2\n7.等待30s"
sub module: TCP
summary: AP mode, keep alive test
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -2165,7 +2163,7 @@ test cases:
-K -s <sock1> -t GET \n6.lev -K -s <sock1> -t SET -i 30 -d 3 -c 2\n7.PC往8266发送数据\n8.8266往PC上发送数据\n9.PC往8266发送146000数据\n10.8266往PC上发送1460*100数据\n11.等待30s"
sub module: TCP
summary: AP mode, keep alive interact with TCP send
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: socket option test
version: v1 (2016-8-15)
@ -2213,7 +2211,7 @@ test cases:
6.8266往PC上发送5字节数据
sub module: TCP
summary: do TCP send after WIFI disconnected
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2261,7 +2259,7 @@ test cases:
6.关闭建立的socket1连接
sub module: TCP
summary: "close TCP socket after WIFI \ndisconnected"
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2305,7 +2303,7 @@ test cases:
\n6.8266往PC上发送5字节数据"
sub module: TCP
summary: do TCP send after mode changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2349,7 +2347,7 @@ test cases:
\n6.关闭建立的socket1连接"
sub module: TCP
summary: close TCP socket after mode changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2399,7 +2397,7 @@ test cases:
6.target1上使用socket1发送数据等待 90 分钟
sub module: TCP
summary: do TCP send after PC NIC disabled
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2442,7 +2440,7 @@ test cases:
PC的iptest_tcp_port1\n4.PC与target1创建好TCP 连接有ACCEPT\n5.PC上网卡禁止掉 \n6.关闭建立的socket1连接"
sub module: TCP
summary: close TCP socket after PC NIC disabled
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2492,7 +2490,7 @@ test cases:
ip \n7.查询sta ip 地址是否生效\n8.8266往PC上发送5字节数据"
sub module: TCP
summary: do TCP send after IP changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2542,7 +2540,7 @@ test cases:
ip \n7.查询sta ip 地址是否生效\n8.关闭建立的socket1连接"
sub module: TCP
summary: close TCP socket after IP changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2594,7 +2592,7 @@ test cases:
7.8266往PC socket1上发送5字节数据
sub module: TCP
summary: do TCP send after socket changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2646,7 +2644,7 @@ test cases:
7.关闭socket2连接
sub module: TCP
summary: close TCP send after socket changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP handling abnormal event
version: v1 (2016-8-15)
@ -2683,7 +2681,7 @@ test cases:
2. target try to connect to TCP server with PC NIC IP
sub module: TCP
summary: PC do not reply TCP SYN of target
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: TCP connect and disconnect abnormal case
version: v1 (2015-8-15)
@ -2747,7 +2745,7 @@ test cases:
10.等待30s
sub module: TCP
summary: Test socket with so_keepalive option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -2778,7 +2776,7 @@ test cases:
2.target1上创建TCP socket,bind test_udp_port1
sub module: TCP
summary: Test socket with so_reuseaddr option closed on TCP submodule
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -2830,7 +2828,7 @@ test cases:
sub module: TCP
summary: Test socket with so_reuseaddr option opened that close TCP connection not
react immediately on ESP32
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -2862,7 +2860,7 @@ test cases:
sub module: TCP
summary: Test socket with so_reuseaddr option opened that build two tcp sockets
by binding same ip and port on ESP32
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -2893,7 +2891,7 @@ test cases:
- - R PC_COM C OK
- - SSC SSC1 soc -S -s <sock1> -l 5000
- - P SSC1 RE SEND:\d+,OK
- - SSC SSC1 soc -S -s <sock1> -l 5000
- - SSC SSC1 soc -S -s <sock1> -l 5000 -n 4
- - P SSC1 RE SEND:\d+,ERROR,11
execution time: 0.0
expected result: |-
@ -2923,7 +2921,7 @@ test cases:
10.target1 send 5000 bytes to PC
sub module: TCP
summary: Test socket with so_sndtimeo option on ESP32
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -2978,7 +2976,7 @@ test cases:
8.PC send 5 bytes to target1
sub module: TCP
summary: Test socket with so_rcvtimeo option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3017,7 +3015,7 @@ test cases:
4.target1上使用步骤2创建的socket去连接 PC的iprandom_port, 获取 error code
sub module: TCP
summary: Test socket with so_error option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3066,7 +3064,7 @@ test cases:
7.查询空闲ram
sub module: TCP
summary: Test socket with so_linger option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3115,7 +3113,7 @@ test cases:
sub module: TCP
summary: Test socket with so_reuseaddr option opened that close TCP connection not
react immediately on 8266_RTOS
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3148,7 +3146,7 @@ test cases:
sub module: TCP
summary: Test socket with so_reuseaddr option opened that build two tcp sockets
by binding same ip and port on 8266_RTOS
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3209,7 +3207,7 @@ test cases:
10.target1 send 1500 bytes to PC
sub module: TCP
summary: Test socket with so_sndtimeo option on 8266_RTOS
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3262,7 +3260,7 @@ test cases:
8.关闭socket
sub module: TCP
summary: Test socket with Maxconnect option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3311,7 +3309,7 @@ test cases:
7.关闭socket
sub module: TCP
summary: Test socket with MaxConnectNum option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3356,7 +3354,7 @@ test cases:
6.等待30s
sub module: TCP
summary: Test socket with Registtime option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3393,7 +3391,7 @@ test cases:
4.target1上对步骤2创建的socket设置 Abort 属性
sub module: TCP
summary: Test socket with Abort option
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3439,7 +3437,7 @@ test cases:
sub module: TCP
summary: Test socket with so_reuseaddr option opened that close TCP connection not
react immediately on 8266_NonOS
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3469,7 +3467,7 @@ test cases:
sub module: TCP
summary: Test socket with so_reuseaddr option opened that build two tcp sockets
by binding same ip and port on 8266_NonOS
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -3506,7 +3504,7 @@ test cases:
Loop executing step 1
sub module: TCP
summary: test possible TCP connect/disconnect method
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: function + stress
test point 2: TCP connect and disconnect test
version: v2 (2016-11-15)
@ -3584,7 +3582,7 @@ test cases:
2. PC send random length data to target
sub module: TCP
summary: send random length segment to target
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: stable
test point 2: TCP stable test
version: v2 (2016-11-15)
@ -3716,6 +3714,39 @@ test cases:
test point 1: stress
test point 2: TCP stress test
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_TCP_5106
SDK: |-
8266_NonOS
8266_RTOS
ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stable
cmd set:
- TCPStress/TCPRandomSend
- - delay_config = [0, 0.01, 0.1, 0.5, 1]
- - dummy
- - send_count = 1000
- - ''
- - test_time = 300
- - ''
execution time: 12.0
expected result: |-
1. succeed
2. succeed
initial condition: T1_ETH
level: Integration
module: TCPIP
steps: |-
1. create TCP connection
2. PC send random length data to target
sub module: TCP
summary: send random length segment to target for Ethernet
test environment: ETH_T1_1
test point 1: stable
test point 2: TCP stable test
version: v2 (2016-11-15)
- CI ready: 'Yes'
ID: TCPIP_TCP_5201
SDK: |-
@ -3751,7 +3782,7 @@ test cases:
3. do send/recv on all tcp connections
sub module: TCP
summary: TCP send/recv stress test
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: stress
test point 2: TCP stress test
version: v2 (2016-11-15)
@ -3788,7 +3819,7 @@ test cases:
2. send specified pattern on both direction
sub module: TCP
summary: TCP send/recv data validation
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: stress
test point 2: TCP stress test
version: v2 (2016-11-15)
@ -3827,6 +3858,43 @@ test cases:
test point 1: stress
test point 2: TCP stress test
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: TCPIP_TCP_5204
SDK: |-
8266_NonOS
8266_RTOS
ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stress
cmd set:
- TCPStress/TCPDataValidation
- - test_time = 1440
- - dummy
- - tx_enable = True
- - ''
- - rx_enable = True
- - ''
- - conn_num = 1
- - ''
- - send_len = 1024
- - ''
execution time: 24.0
expected result: |-
1. succeed
2. verify reciveid data on target and PC succeed
initial condition: T1_ETH
level: Integration
module: TCPIP
steps: |-
1. create TCP connection
2. send specified pattern on both direction
sub module: TCP
summary: TCP send/recv data validation for Ethernet
test environment: ETH_T1_1
test point 1: stress
test point 2: TCP stress test
version: v2 (2016-11-15)
- CI ready: 'No'
ID: TCPIP_TCP_5301
SDK: |-
@ -3937,7 +4005,7 @@ test cases:
Loop for step 1-2
sub module: TCP
summary: TCP throughput Tx for Ethernet
test environment: SSC_T1_1
test environment: ETH_T1_1
test point 1: stress
test point 2: TCP stress test
version: v1 (2016-8-15)
@ -3975,7 +4043,7 @@ test cases:
Loop for step 1-2
sub module: TCP
summary: TCP throughput Rx for Ethernet
test environment: SSC_T1_1
test environment: ETH_T1_1
test point 1: stress
test point 2: TCP stress test
version: v1 (2016-8-15)
@ -4013,7 +4081,7 @@ test cases:
Loop for step 1-3
sub module: TCP
summary: Eth random close while sending packets
test environment: SSC_T1_1
test environment: ETH_T1_1
test point 1: stress
test point 2: TCP stress test
version: v1 (2016-8-15)
@ -4051,7 +4119,7 @@ test cases:
3. send TCP packet
4. calculate the troughput
sub module: TCP
summary: STA TCP throughput while connecting with softAP
summary: STA TCP throughput Tx while connected with softAP
test environment: SSC_T2_ShieldBox2
test point 1: Performance test
test point 2: TCP throughput
@ -4090,11 +4158,51 @@ test cases:
3. send TCP packet
4. calculate the troughput
sub module: TCP
summary: STA TCP throughput while connecting with softAP
summary: STA TCP throughput Rx while connected with softAP
test environment: SSC_T2_ShieldBox2
test point 1: Performance test
test point 2: TCP throughput
version: v1 (2016-10-18)
- CI ready: 'No'
ID: TCPIP_TCP_5701
SDK: |-
8266_NonOS
8266_RTOS
ESP32_IDF
Test App: SSC
auto test: 'Yes'
category: Stress
cmd set:
- StableTest/EthGetIP
- - test_count = 5000
- [dummy]
comment: ''
execution time: 5.0
expected result: '1. succeed
2. succeed
3. succeed
4. succeed'
initial condition: None
initial condition description (auto): none
level: Integration
module: TCPIP
steps: |-
1. reboot
2. open eth
3. delay 10s
4. ip query
sub module: TCP
summary: Eth get ip test
test environment: ETH_T1_1
test point 1: stress
test point 2: TCP stress test
version: v1 (2016-8-15)
- CI ready: 'No'
ID: TCPIP_TCP_6001
SDK: ESP32_IDF, 8266_NonOS, 8266_RTOS

View file

@ -35,7 +35,7 @@ test cases:
4.target1上创建TCP socket3, target_udp_port1
sub module: UDP
summary: STA mode, udp bind test. use different ip, port
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -81,7 +81,7 @@ test cases:
5.target1上使用步骤3创建的socket1往pc_ip2test_tcp_port2上发送10字节数据
sub module: UDP
summary: STA mode, sendto test. use different ip, port
test environment: SSC_T1_1
test environment: SSC_T1_9
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -132,7 +132,7 @@ test cases:
6.target1上使用步骤2创建的socket1往pc_iptest_tcp_port1上发送1472*10字节数据
sub module: UDP
summary: STA mode, sendto test with different length
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -176,7 +176,7 @@ test cases:
5.target1上使用步骤2创建的socket1往pc_iptest_tcp_port1上发送1473字节数据
sub module: UDP
summary: STA mode, sendto test with different length
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -229,7 +229,7 @@ test cases:
7.PC往8266上发送1472字节数据
sub module: UDP
summary: STA mode, recvfrom basic test
test environment: SSC_T1_1
test environment: SSC_T1_9
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -261,7 +261,7 @@ test cases:
2.关闭socket1
sub module: UDP
summary: STA mode, close UDP sockets test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -305,7 +305,7 @@ test cases:
5.target1上UDP传输Bind socket5,本地ip target_udp_port5
sub module: UDP
summary: STA mode, create max udp socket test
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -336,8 +336,8 @@ test cases:
1.target1上UDP传输Bind socket1,本地ip target_udp_port1
2.target1上查询创建socket信息
sub module: UDP
summary: STA mode, get active socket info test
test environment: SSC_T1_1
summary: STA mode, UDP get active socket info test
test environment: SSC_T1_6
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -377,7 +377,7 @@ test cases:
4.target1上创建TCP socket3, target_udp_port1
sub module: UDP
summary: AP mode, udp bind test. use different ip, port
test environment: SSC_T1_1
test environment: SSC_T1_8
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -430,7 +430,7 @@ test cases:
5.target1上使用步骤3创建的socket1往pc_ip2test_tcp_port2上发送10字节数据
sub module: UDP
summary: AP mode, sendto test. use different ip, port
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -482,7 +482,7 @@ test cases:
6.target1上使用步骤2创建的socket1往pc_iptest_tcp_port1上发送1472*10字节数据
sub module: UDP
summary: AP mode, sendto test with different length
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -526,7 +526,7 @@ test cases:
5.target1上使用步骤2创建的socket1往pc_iptest_tcp_port1上发送1473字节数据
sub module: UDP
summary: AP mode, sendto test with different length
test environment: SSC_T1_1
test environment: SSC_T1_7
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -583,7 +583,7 @@ test cases:
7.PC往8266上发送1472字节数据
sub module: UDP
summary: AP mode, recvfrom basic test
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -615,7 +615,7 @@ test cases:
2.关闭socket1
sub module: UDP
summary: AP mode, close UDP sockets test
test environment: SSC_T1_1
test environment: SSC_T1_8
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -659,7 +659,7 @@ test cases:
5.target1上UDP传输Bind socket5,本地ip target_udp_port5
sub module: UDP
summary: AP mode, create max udp socket test
test environment: SSC_T1_1
test environment: SSC_T1_8
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -690,8 +690,8 @@ test cases:
1.target1上UDP传输Bind socket1,本地ip target_udp_port1
2.target1上查询创建socket信息
sub module: UDP
summary: AP mode, get active socket info test
test environment: SSC_T1_1
summary: AP mode, UDP get active socket info test
test environment: SSC_T1_8
test point 1: basic function
test point 2: use UDP SAP (socket/espconn API) with different parameter
version: v1 (2016-8-15)
@ -744,8 +744,8 @@ test cases:
7.PC往8266上发送1472字节数据
8.PC往8266上发送1472字节数据
sub module: UDP
summary: STA mode, recv buffer test
test environment: SSC_T1_1
summary: STA mode, UDP recv buffer test
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: use UDP SAP (socket/espconn API) in different state
version: v2 (2016-10-19)
@ -800,8 +800,8 @@ test cases:
7.PC往8266上发送1472字节数据
8.PC往8266上发送1472字节数据
sub module: UDP
summary: AP mode, recv buffer test
test environment: SSC_T1_1
summary: AP mode, UDP recv buffer test
test environment: SSC_T1_7
test point 1: abnormal/special use
test point 2: use UDP SAP (socket/espconn API) in different state
version: v2 (2016-10-19)
@ -846,7 +846,7 @@ test cases:
5.target1上使用步骤2创建的socket1往pc_iptest_tcp_port1上发送5字节数据
sub module: UDP
summary: do UDP send after WIFI disconnected
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: UDP handling abnormal event
version: v1 (2016-8-15)
@ -891,7 +891,7 @@ test cases:
5.关闭建立的socket1连接
sub module: UDP
summary: "close UDP socket after WIFI \ndisconnected"
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: UDP handling abnormal event
version: v1 (2016-8-15)
@ -933,7 +933,7 @@ test cases:
mode \n5.8266往PC上发送5字节数据"
sub module: UDP
summary: do UDP send after mode changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: UDP handling abnormal event
version: v1 (2016-8-15)
@ -975,7 +975,7 @@ test cases:
mode \n5.关闭建立的socket1连接"
sub module: UDP
summary: close UDP socket after mode changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: UDP handling abnormal event
version: v1 (2016-8-15)
@ -1017,7 +1017,7 @@ test cases:
\n5.关闭建立的socket1连接"
sub module: UDP
summary: close UDP socket after PC NIC disabled
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: UDP handling abnormal event
version: v1 (2016-8-15)
@ -1065,7 +1065,7 @@ test cases:
1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.8266往PC上发送5字节数据"
sub module: UDP
summary: do UDP send after IP changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: UDP handling abnormal event
version: v1 (2016-8-15)
@ -1113,7 +1113,7 @@ test cases:
1\n5.设置sta ip \n6.查询sta ip 地址是否生效\n7.关闭建立的socket1连接"
sub module: UDP
summary: close UDP socket after IP changed
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: abnormal/special use
test point 2: UDP handling abnormal event
version: v1 (2016-8-15)
@ -1144,7 +1144,7 @@ test cases:
2.target1上创建UDP socket,bind test_udp_port1
sub module: UDP
summary: Test socket with so_reuseaddr option closed on UDP submodule
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -1176,7 +1176,7 @@ test cases:
sub module: UDP
summary: Test socket with so_reuseaddr option opened that build two udp sockets
by binding same port on ESP32
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -1209,7 +1209,7 @@ test cases:
sub module: UDP
summary: Test socket with so_reuseaddr option opened that build two udp sockets
by binding same port on 8266_RTOS
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: basic function
test point 2: socket test with different option
version: v1 (2016-8-15)
@ -1248,7 +1248,7 @@ test cases:
3. do send/recv on all udp
sub module: UDP
summary: UDP send/recv stress test
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: stress
test point 2: UDP stress test
version: v2 (2016-11-15)
@ -1285,7 +1285,7 @@ test cases:
2. create UDP and recv data for several seconds
sub module: UDP
summary: UDP loss rate on DUT Rx
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: Performance test
test point 2: UDP stress test
version: v1 (2016-10-18)
@ -1322,7 +1322,7 @@ test cases:
2. create UDP and recv data for several seconds
sub module: UDP
summary: UDP loss rate on DUT Tx
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: Performance test
test point 2: UDP stress test
version: v1 (2016-10-18)
@ -1337,7 +1337,7 @@ test cases:
category: Stress
cmd set:
- UDPStress/UDPBroadcast
- - test_time = 0.2
- - test_time = 30
- - dummy
- - send_len = 20
- - ''
@ -1359,7 +1359,7 @@ test cases:
2. create UDP and recv data for several seconds
sub module: UDP
summary: UDP broadcase loss rate on DUT Rx
test environment: SSC_T1_1
test environment: SSC_T1_6
test point 1: Performance test
test point 2: UDP stress test
version: v1 (2016-10-18)
@ -1480,7 +1480,7 @@ test cases:
sub module: UDP
summary: STA connect to softAP, STA send UDP to softAP, calculate the UDP lose on
softAP
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: Performance test
test point 2: UDP stress test
version: v1 (2016-10-18)
@ -1520,7 +1520,7 @@ test cases:
sub module: UDP
summary: STA connect to softAP, softAP send UDP to STA, calculate the UDP lose on
STA
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: Performance test
test point 2: UDP stress test
version: v1 (2016-10-18)
@ -1634,7 +1634,7 @@ test cases:
Loop for step 1-2
sub module: UDP
summary: UDP throughput Tx for Ethernet
test environment: SSC_T1_1
test environment: ETH_T1_1
test point 1: stress
test point 2: UDP stress test
version: v1 (2016-8-15)
@ -1672,7 +1672,7 @@ test cases:
Loop for step 1-2
sub module: UDP
summary: UDP throughput Rx for Ethernet
test environment: SSC_T1_1
test environment: ETH_T1_1
test point 1: stress
test point 2: UDP stress test
version: v1 (2016-8-15)
@ -1710,7 +1710,7 @@ test cases:
3. DUT calculate the packet lose rate
sub module: UDP
summary: UDP loss rate on DUT Rx for Eth
test environment: SSC_T1_1
test environment: ETH_T1_1
test point 1: Performance test
test point 2: UDP stress test
version: v1 (2016-10-18)
@ -1748,7 +1748,7 @@ test cases:
3. send UDP packet
4. calculate the troughput
sub module: UDP
summary: STA UDP throughput while connecting with softAP
summary: STA UDP throughput Tx while connected with softAP
test environment: SSC_T2_ShieldBox2
test point 1: Performance test
test point 2: UDP throughput
@ -1787,7 +1787,7 @@ test cases:
3. send UDP packet
4. calculate the troughput
sub module: UDP
summary: STA UDP throughput while connecting with softAP
summary: STA UDP throughput Rx while connected with softAP
test environment: SSC_T2_ShieldBox2
test point 1: Performance test
test point 2: UDP throughput

View file

@ -39,7 +39,7 @@ test cases:
为target1_mac\n6.target1 设置softAP mode 下的mac 为target1_ap_mac\n"
sub module: MAC Address
summary: set mac, query mac
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: mac address function test
version: v1 (2016-8-15)
@ -93,7 +93,7 @@ test cases:
jap target1\n8.target1 查询连接到的sta \n9.target2 设置sta mode 下的mac 为 target2_mac\n"
sub module: MAC Address
summary: set mac and do scan/JAP/SAP
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: mac address function test
version: v1 (2016-8-15)

View file

@ -51,7 +51,7 @@ test cases:
和pwd,加密方式 t 5 错误的加密方式\n12.target2上查询 target_ssid"
sub module: WIFI Connect
summary: station SAP+JAP test, different encryption
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: SAP/JAP with different config
version: v1 (2016-8-15)
@ -101,7 +101,7 @@ test cases:
6.target 2 上查询target_ssid
sub module: WIFI Connect
summary: station SAP+JAP test, different channel
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: SAP/JAP with different config
version: v1 (2016-8-15)
@ -150,7 +150,7 @@ test cases:
4.target 2上scan target_ap_mac
sub module: WIFI Connect
summary: station SAP+JAP test, ssid hidden
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: SAP/JAP with different config
version: v1 (2016-8-15)
@ -192,7 +192,7 @@ test cases:
4.PC WIFI CONNECT target1
sub module: WIFI Connect
summary: station SAP test, max allowed sta
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: SAP/JAP with different config
version: v1 (2016-8-15)
@ -232,7 +232,7 @@ test cases:
4.查询target1 JAP 是DISCONN
sub module: WIFI Connect
summary: JAP query test
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: query JAP status
version: v1 (2016-8-15)
@ -265,10 +265,93 @@ test cases:
2.target 1上查询到跟设置AP时一致
sub module: WIFI Connect
summary: AP config query test
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: query AP config
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: WIFI_CONN_0302
SDK: |-
8266_NonOS
8266_RTOS
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 sta -S
- - R SSC1 C +SCAN_DONE:OK
- - SSC SSC1 sta -C -s <ap_ssid> -p <ap_password>
- - P SSC1 C +JAP:CONNECTED
- P SSC1 C +SCANDONE
- - SSC SSC1 sta -D
- - R SSC1 C +QAP:OK
- - SSC SSC1 sta -C -s <ap_ssid> -p <ap_password>
- - ''
- - SSC SSC1 sta -S
- - P SSC1 C +JAP:CONNECTED
- P SSC1 C +SCANDONE
execution time: 0.0
expected result: |
2. scan succeed, JAP succeed
5. JAP succeed, scan succeed
initial condition: STAM1
level: Integration
module: WIFI MAC
steps: |
1. target 1 STA join AP
2. target 1 STA scan before JAP succeed
3. target 1 quite AP
4. target 1 scan
5. target 1 JAP before scan succeed
sub module: WIFI Connect
summary: JAP during scan
test environment: SSC_T1_5
test point 1: interaction
test point 2: Conn interact with other WiFi operation
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: WIFI_CONN_0302
SDK: |-
ESP32_IDF
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 sta -S
- - R SSC1 C +SCAN_DONE:OK
- - SSC SSC1 sta -C -s <ap_ssid> -p <ap_password>
- - P SSC1 C +JAP:CONNECTED
- P SSC1 C +SCANFAIL
- - SSC SSC1 sta -D
- - R SSC1 C +QAP:OK
- - SSC SSC1 sta -C -s <ap_ssid> -p <ap_password>
- - ''
- - SSC SSC1 sta -S
- - P SSC1 C +JAP:CONNECTED
- P SSC1 C +SCAN:ERROR
execution time: 0.0
expected result: |
2. scan failed, JAP succeed
5. JAP succeed, scan failed
initial condition: STAM1
level: Integration
module: WIFI MAC
steps: |
1. target 1 STA join AP
2. target 1 STA scan before JAP succeed
3. target 1 quite AP
4. target 1 scan
5. target 1 JAP before scan succeed
sub module: WIFI Connect
summary: JAP during scan
test environment: SSC_T1_5
test point 1: interaction
test point 2: Conn interact with other WiFi operation
version: v1 (2016-8-15)
- CI ready: 'Yes'
ID: WIFI_CONN_0401
SDK: |-
@ -319,7 +402,7 @@ test cases:
7.系统重启后target1 自动重连AP
sub module: WIFI Connect
summary: auto reconnect test
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: power on auto reconnect test
version: v1 (2016-8-15)
@ -383,7 +466,7 @@ test cases:
修改mode 为sta mode\n9.等待15starget1 修改mode 为softAP mode"
sub module: WIFI Connect
summary: reconnect policy test
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: reconnect policy test
version: v1 (2016-8-15)
@ -438,7 +521,7 @@ test cases:
6.target2 断开target1 连接
sub module: WIFI Connect
summary: will not do reconnect after manually disconnected
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: abnormal/special use
test point 2: reconnect policy test
version: v1 (2016-8-15)
@ -528,7 +611,7 @@ test cases:
4.查询到两个sta 连接到target1 上
sub module: WIFI Connect
summary: list stations connected to soft ap test
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: list SoftAP connected station
version: v1 (2016-8-15)
@ -686,7 +769,7 @@ test cases:
6. set target1 softap auth mode 0, wait sta connected
sub module: WIFI Connect
summary: test auth change event
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: wifi auth changed event test
version: v1 (2016-8-15)
@ -828,7 +911,7 @@ test cases:
5. target2 connect to target1 with correct password
sub module: WIFI Connect
summary: test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT
test environment: SSC_T2_1
test environment: SSC_T2_2
test point 1: basic function
test point 2: wifi disconnect reason test
version: v1 (2016-8-15)
@ -892,7 +975,7 @@ test cases:
4. check heap size
sub module: WIFI Connect
summary: wifi start and stop, heap size unchanged
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: wifi start and stop, heap size unchanged
version: v1 (2016-12-31)
@ -917,7 +1000,7 @@ test cases:
1. sta connect
sub module: WIFI Connect
summary: sta connect after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -946,7 +1029,7 @@ test cases:
2. query sta state
sub module: WIFI Connect
summary: sta reconnect start and connect fail after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -971,7 +1054,7 @@ test cases:
1. sta disconnect
sub module: WIFI Connect
summary: station disconnect after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -996,7 +1079,7 @@ test cases:
1. query sta state
sub module: WIFI Connect
summary: query sta state after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1021,7 +1104,7 @@ test cases:
1. sta scan ssid and pwd
sub module: WIFI Connect
summary: sta scan after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1046,7 +1129,7 @@ test cases:
1. ap connect ssid and pwd
sub module: WIFI Connect
summary: ap connect after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1071,7 +1154,7 @@ test cases:
1. ap disconnect
sub module: WIFI Connect
summary: ap disconnect after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1096,7 +1179,7 @@ test cases:
1. ap list station
sub module: WIFI Connect
summary: ap list station after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1121,7 +1204,7 @@ test cases:
1. query ap config
sub module: WIFI Connect
summary: query ap config after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1158,7 +1241,7 @@ test cases:
4. ap set ssid and pwd
sub module: WIFI Connect
summary: ap set ssid and pwd after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1183,7 +1266,7 @@ test cases:
1. query mac
sub module: WIFI Connect
summary: query mac after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1215,8 +1298,8 @@ test cases:
2. set ap mac
3. set station mac
sub module: WIFI Connect
summary: set mac after WiFi stop
test environment: SSC_T1_1
summary: enable AP mode after WiFi stop and set AP mac
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1248,8 +1331,8 @@ test cases:
2. set station mac
3. query station mac
sub module: WIFI Connect
summary: query mac after WiFi stop
test environment: SSC_T1_1
summary: enable STA mode after WiFi stop and set STA mac
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1281,8 +1364,8 @@ test cases:
2. set station mac
3. set ap mac
sub module: WIFI Connect
summary: set mac after WiFi stop
test environment: SSC_T1_1
summary: enable STA mode after WiFi stop and set AP mac
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1307,7 +1390,7 @@ test cases:
1. set channel
sub module: WIFI Connect
summary: set channel after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1336,7 +1419,7 @@ test cases:
2. query channel
sub module: WIFI Connect
summary: query channel after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1361,7 +1444,7 @@ test cases:
1. query current mode
sub module: WIFI Connect
summary: be AP mode after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1386,7 +1469,7 @@ test cases:
1. set STA mode
sub module: WIFI Connect
summary: set STA mode after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1411,7 +1494,7 @@ test cases:
1. set AP mode
sub module: WIFI Connect
summary: set ap mode after WiFi stop
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: use WiFi API after WiFi stop
version: v1 (2016-12-31)
@ -1448,7 +1531,7 @@ test cases:
4. wifi stop
sub module: WIFI Connect
summary: incorrect deinit stop flow
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: WiFi deinit and stop
version: v1 (2016-12-31)
@ -1485,7 +1568,7 @@ test cases:
4. wifi stop
sub module: WIFI Connect
summary: incorrect deinit start flow
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: WiFi deinit and start
version: v1 (2016-12-31)
@ -1537,8 +1620,8 @@ test cases:
7. wifi deinit
8. wifi start
sub module: WIFI Connect
summary: incorrect deinit stop flow
test environment: SSC_T1_1
summary: incorrect init start flow
test environment: SSC_T1_4
test point 1: basic function
test point 2: WiFi deinit and stop
version: v1 (2016-12-31)
@ -1782,7 +1865,7 @@ test cases:
2. 1 SSC connect with AP
3. check connection status within 24 hours
sub module: WIFI Connect
summary: connection stable
summary: WiFi STA connection stable test
test environment: SSC_T1_1
test point 1: stress + function
test point 2: connection keep alive stress test
@ -1819,7 +1902,7 @@ test cases:
3. SSC stop send pkt
4. SSC connect ap
sub module: WIFI Connect
summary: connection stable
summary: Switch channel when sending WiFi packets
test environment: SSC_T1_1
test point 1: stress
test point 2: connect ap
@ -1965,8 +2048,65 @@ test cases:
module: WIFI MAC
steps: 1. set sta mode 2. disconnect sta 3. sta connect ap
sub module: WIFI Connect
summary: sta connect ap
summary: STA connect to AP compatibility test
test environment: SSC_T1_IOT1
test point 1: Compatibility Test test point
test point 2: WIFI compatibility test
version: v1 (2016-10-23)
- CI ready: 'No'
ID: WIFI_CONN_0704
SDK: All
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 sta -C -s <wep_ap_ssid> -p <wep_ap_password>
- - R SSC1 C +JAP:OK
- R SSC1 NC +JAPAUTHCHANGED C +JAP:CONNECTED
execution time: 0
expected result: 1. sta connect ap suc and no +JAPAUTHCHANGED found
initial condition: STAM1
level: Integration
module: WIFI MAC
steps: 1. sta JAP
sub module: WIFI Connect
summary: sta connect wep encrypt ap
test environment: SSC_T1_WEP
test point 1: basic function
test point 2: ap connect test
version: v1 (2016-10-23)
- CI ready: 'No'
ID: WIFI_CONN_9902
SDK: All
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Performance
cmd set:
- WiFiStress/WifiStaConnectionHolder
- - test_count = 10
- - ''
- - retry_count = 1
- - ''
execution time: 1
expected result: |-
1. set SSC1 AP+STA mode, SSC2 AP mode, SSC3 STA mode
2. SSC3 connect SSC1
3. SSC2 random set ap channel
4. SSC1 connect SSC2
initial condition: T3_1
level: Integration
module: WIFI MAC
steps: |-
1. set mode suc
2. connect suc
3. set channel suc
4. connect suc
sub module: WIFI Connect
summary: STA keep connected with AP stable test
test environment: SSC_T3_1
test point 1: AP switch channel dut Connection holder Test test point
test point 2: WIFI Connection holder test
version: v1 (2016-10-23)

View file

@ -43,7 +43,7 @@ test cases:
6.target1断开AP
sub module: WIFI Mode
summary: mode switch test (sta mode)
test environment: SSC_T2_1
test environment: SSC_T2_3
test point 1: basic function
test point 2: wifi mode fucntion
version: v1 (2016-8-15)
@ -84,7 +84,7 @@ test cases:
4.target1 DISCONN AP
sub module: WIFI Mode
summary: mode switch test (AP mode)
test environment: SSC_T2_1
test environment: SSC_T2_3
test point 1: basic function
test point 2: wifi mode fucntion
version: v1 (2016-8-15)
@ -129,7 +129,7 @@ test cases:
5.target2 上查询target_ssid
sub module: WIFI Mode
summary: mode switch test (STA+AP mode)
test environment: SSC_T2_1
test environment: SSC_T2_3
test point 1: basic function
test point 2: wifi mode fucntion
version: v1 (2016-8-15)

View file

@ -33,7 +33,7 @@ test cases:
3.target2 scan <target_tmp_ssid>
sub module: WIFI Scan
summary: scan with scan config ssid
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan with different config
version: v1 (2016-8-15)
@ -66,7 +66,7 @@ test cases:
2.target2上查询<target_ap_mac>
sub module: WIFI Scan
summary: scan with scan config bssid
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan with different config
version: v1 (2016-8-15)
@ -107,7 +107,7 @@ test cases:
4.target2 上查询channel 6的<target_tmp_ssid>
sub module: WIFI Scan
summary: scan with scan config channel
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan with different config
version: v1 (2016-8-15)
@ -157,7 +157,7 @@ test cases:
6.target 2上查询<target_ap_mac>
sub module: WIFI Scan
summary: scan with scan config show hidden
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan with different config
version: v1 (2016-8-15)
@ -207,10 +207,60 @@ test cases:
6.target2 上查询不到<target_tmp_ssid>
sub module: WIFI Scan
summary: scan with several configs
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan with different config
version: v1 (2016-8-15)
- CI ready: 'No'
ID: WIFI_SCAN_0201
SDK: ESP32_IDF
Test App: SSC
allow fail: ''
auto test: 'Yes'
category: Function
cmd set:
- ''
- - SSC SSC1 phy -S -o 1 -m b
- - R SSC1 C +SPHY:protocol
- - SSC SSC1 sta -S
- - R SSC1 P <ap_ssid_11b> P <ap_ssid_11g> P <ap_ssid_11n_20> P <ap_ssid_11n_40>
- - SSC SSC1 phy -S -o 1 -m g
- - R SSC1 C +SPHY:protocol
- - SSC SSC1 sta -S
- - R SSC1 P <ap_ssid_11b> P <ap_ssid_11g> P <ap_ssid_11n_20> P <ap_ssid_11n_40>
- - SSC SSC1 phy -S -o 1 -m n -b 20
- - R SSC1 C +SPHY:protocol
- - SSC SSC1 sta -S
- - R SSC1 P <ap_ssid_11b> P <ap_ssid_11g> P <ap_ssid_11n_20> P <ap_ssid_11n_40>
- - SSC SSC1 phy -S -o 1 -m n -b 40
- - R SSC1 C +SPHY:protocol
- - SSC SSC1 sta -S
- - R SSC1 P <ap_ssid_11b> P <ap_ssid_11g> P <ap_ssid_11n_20> P <ap_ssid_11n_40>
execution time: 0.0
expected result: |-
3. find all 3 ext APs
5. find all 3 ext APs
7. find all 3 ext APs
9. find all 3 ext APs
initial condition: STAM1
level: Integration
module: WIFI MAC
steps: |-
1. 3 ext APs in 11b, 11g, 11n mode
2. STA in 11b mode
3. do all channel scan
4. STA in 11g mode
5. do all channel scan
6. STA in 11n ht20 mode
7. do all channel scan
8. STA in 11n ht40 mode
9. do all channel scan
sub module: WIFI Scan
summary: STA in differnt PHY mode to scan AP in different PHY mode
test environment: SSC_T2_PhyMode
test point 1: basic function
test point 2: Scan in different mode and channel
version: v1 (2015-8-15)
- CI ready: 'No'
ID: WIFI_SCAN_0202
SDK: |-
@ -242,8 +292,8 @@ test cases:
2.target2 jap
3.target2 conn target1 by bssid
sub module: WIFI Scan
summary: do scan/JAP/SAP
test environment: SSC_T2_1
summary: do scan/JAP/SAP with bssid set config
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan function test
version: v1 (2016-8-15)
@ -311,8 +361,8 @@ test cases:
11.target2 scan all channel jap target1
12.target2 jap target1
sub module: WIFI Scan
summary: do scan/JAP/SAP
test environment: SSC_T2_1
summary: do scan/JAP/SAP with scan method and weakest auth mode
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan function test
version: v1 (2016-8-15)
@ -363,8 +413,8 @@ test cases:
6.target2 scan all channel and jap rssi > -1
7.target2 scan all channel and jap target1 rssi > -80
sub module: WIFI Scan
summary: do scan/JAP/SAP
test environment: SSC_T2_1
summary: do scan/JAP/SAP with scan method and weakest rssi
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan function test
version: v1 (2016-8-15)
@ -403,8 +453,8 @@ test cases:
3.target2 scan ap all channel and jap target1 by auth
4.target2 scan ap all channel jap target1 by auth
sub module: WIFI Scan
summary: do scan/JAP/SAP
test environment: SSC_T2_1
summary: do scan/JAP/SAP with scan method and sort method
test environment: SSC_T2_5
test point 1: basic function
test point 2: scan function test
version: v1 (2016-8-15)
@ -456,7 +506,7 @@ test cases:
7.target1 scan type set to 5
sub module: WIFI Scan
summary: do active/passive scan
test environment: SSC_T1_1
test environment: SSC_T1_4
test point 1: basic function
test point 2: scan function test
version: v1 (2016-8-15)
@ -487,7 +537,7 @@ test cases:
2. do scan before scan finished
sub module: WIFI Scan
summary: reject scan request before scan finished
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: interaction
test point 2: Scan interact with other WiFi operation
version: v1 (2015-8-15)
@ -533,7 +583,7 @@ test cases:
3. target 2 scan in AP channel in 11b.g,n,ht40 mode
sub module: WIFI Scan
summary: scan in congest channel
test environment: SSC_T2_1
test environment: SSC_T2_4
test point 1: interaction
test point 2: Scan interact with other WiFi operation
version: v1 (2015-8-15)
@ -573,7 +623,7 @@ test cases:
5. target 1 JAP before scan succeed
sub module: WIFI Scan
summary: scan during JAP
test environment: SSC_T1_1
test environment: SSC_T1_5
test point 1: interaction
test point 2: Scan interact with other WiFi operation
version: v1 (2015-8-15)
@ -617,7 +667,7 @@ test cases:
5. target 2 STA JAP before target 1 STA scan succeed
sub module: WIFI Scan
summary: scan during ext STA join SoftAP
test environment: SSC_T2_1
test environment: SSC_T2_5
test point 1: interaction
test point 2: Scan interact with other WiFi operation
version: v1 (2015-8-15)
@ -669,14 +719,17 @@ test cases:
- - ''
- - test_mode = "conn_by_bssid"
- - ''
execution time: 5.0
expected result: 2. connect success
execution time: 0.2
expected result: |-
1. all routers configure correctly
3. connect success
initial condition: None
level: Integration
module: WIFI MAC
steps: |-
1. 1 SSC target connect PC by Uart.
2. SSC target connect ap by bssid
1. Manually configure the two routers with the same ssid ,password and security mode
2. SSC1 target connect PC by Uart.
3. SSC target connect ap by the specified bssid
sub module: WIFI Scan
summary: connect specify ap test
test environment: SSC_T1_SCANSPECIFIED
@ -695,14 +748,19 @@ test cases:
- - ''
- - test_mode = "conn_max_rssi_ap"
- - ''
execution time: 5.0
expected result: 2. connect success
execution time: 0.2
expected result: |-
1. configure ap right
3. connect success
4. rssi value is the largest of the four routers
initial condition: None
level: Integration
module: WIFI MAC
steps: |-
1. 1 SSC target connect PC by Uart.
2. SSC connect max rssi ap.
1. Manually configure the four routers with the same ssid ,password and security mode
2. 1 SSC target connect PC by Uart.
3. SSC connect max rssi ap.
4. check connection ap's rssi value
sub module: WIFI Scan
summary: connect max rssi ap
test environment: SSC_T1_SCANSPECIFIED
@ -721,14 +779,19 @@ test cases:
- - ''
- - test_mode = "conn_most_security_ap"
- - ''
execution time: 5.0
expected result: 2. connect success
execution time: 0.2
expected result: |-
1. the routers are configured correctly
3. connect success
4. encryption mode is the highest in four routers
initial condition: None
level: Integration
module: WIFI MAC
steps: |-
1. 1 SSC target connect PC by Uart.
2. SSC connect max rssi ap
1. Manually configure the four routers with the same ssid ,password and different security mode
2. target1 connect PC by Uart.
3. target1 connect the highest encryption mode ap
4. check connection ap's security mode
sub module: WIFI Scan
summary: connect most security ap
test environment: SSC_T1_SCANSPECIFIED
@ -747,14 +810,17 @@ test cases:
- - ''
- - test_mode = "conn_setting_ap"
- - ''
execution time: 5.0
expected result: 2. connect success
execution time: 0.2
expected result: |-
1. the routers are configured correctly
3. connect success
initial condition: None
level: Integration
module: WIFI MAC
steps: |-
1. 1 SSC target connect PC by Uart.
2. SSC connect setting ap
1. Manually configure the four routers with the same ssid different password
2. target1 connect PC by Uart.
3. target1 connect setting ap
sub module: WIFI Scan
summary: connect setting ap
test environment: SSC_T1_SCANSPECIFIED
@ -775,17 +841,23 @@ test cases:
- - ''
- - apc_num_list = [1,3]
- - ''
execution time: 5.0
expected result: 2. connect success
execution time: 0.5
expected result: |-
1. the routers are configured correctly
3. ap1 power on
4. connect success
5. ap2 power on and ap1 power off
6. connect success
initial condition: None
level: Integration
module: WIFI MAC
steps: |-
1. 1 SSC target connect PC by Uart.
2. ap1 power on by apc
3. SSC connect ap
4. ap1 power off and ap2 power on
5. SSC auto connect ap2.
1. Manually configure the two routers with the same ssid ,password different security mode
2. target1 connect PC by Uart.
3. ap1 power on by apc
4. atrget1 connect ap
5. ap1 power off and ap2 power on
6. atrget1 auto connect ap2.
sub module: WIFI Scan
summary: reconnect same ssid ap
test environment: SSC_T1_SCANSPECIFIED
@ -806,14 +878,21 @@ test cases:
- - ''
- - rssi_threshold = 60
- - ''
execution time: 5.0
expected result: 2. connect success
- - low_rssi_num = 1
- - ''
execution time: 0.3
expected result: |-
1. the routers are configured correctly
3. connect success
4. connect to the correct ap
initial condition: None
level: Integration
module: WIFI MAC
steps: |-
1. 1 SSC target connect PC by Uart.
2. SSC1 connect ap
1. manuall configure two routers with the same ssid password and below rssi_threshold ap's channel at the front
2. target1 connect PC by Uart.
3. atrget1 connect ap
4. check connection ap's bssid
sub module: WIFI Scan
summary: quick connect ap
test environment: SSC_T1_SCANSPECIFIED
@ -824,22 +903,26 @@ test cases:
ID: WIFI_SCAN_5207
SDK: ESP32_IDF
Test App: SSC
auto test: 'Yes'
auto test: 'No'
category: Stress
cmd set:
- WiFiStress/WifiScanOptimize
- - test_times = 10
- - ''
execution time: 5.0
expected result: 2. connect success
cmd set: ''
execution time: 0.3
expected result: |-
1. the routers are configured correctly
3. set suc
5. burn suc
6. set mode ok and SSC connected to the open security mode ap auto
initial condition: None
level: Integration
module: WIFI MAC
steps: |-
1. 1 SSC target connect PC by Uart.
2. make menuconfig
3. write ap ssid
4. connect ap auto
1. configure four router with the same ssid and one of them security mode is open
2. target1 connect PC by Uart.
3. set the ssid of the router in the manuconfig but not the password
4. save the setting and compile
5. burn bin files
6. set target1 to sta mode
7. loop 1,2,3,4 ten times
sub module: WIFI Scan
summary: connect open security ap
test environment: SSC_T1_SCANSPECIFIED

View file

@ -10,18 +10,78 @@ test environment:
test environment detail: |-
PC has 2 wired NIC connected to AP.
PC has 1 WiFi NIC.
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
- tag: ETH_T1_1
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
PC connected to AP by wired NIC.
1 ETH DUT connect with PC by UART, connect to AP by wired NIC.
- tag: SSC_T1_2
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
Able to access WAN after connect to AP.
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_3
<<: *TEST_ENV
Target Count: 1
test environment detail: PC has one BT adapter (dongle). 1 SSC target connect with
test environment detail: PC has one BT adapter (dongle). 1 SSC DUT connect with
PC by UART.
- tag: SSC_T1_4
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_5
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
1 SSC DUT connect with PC by UART.
AP placed near DUT.
- tag: SSC_T1_6
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
1 SSC DUT connect with PC by UART.
AP placed near DUT.
PC has 1 wired NIC connected to AP.
- tag: SSC_T1_7
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
1 SSC DUT connect with PC by UART.
PC has 1 WiFi NIC.
AP placed near DUT and PC.
- tag: SSC_T1_8
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
1 SSC DUT connect with PC by UART.
AP placed near DUT and PC.
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
- tag: SSC_T1_9
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
PC has 2 wired NIC connected to AP.
1 SSC DUT connected to AP.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_10
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
PC has 1 WiFi NIC.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_ARP
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
PC (linux) has 1 wired NIC connected to AP.
AP is configured as update group key every 30s.
PC has 1 WiFi NIC.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_8089
<<: *TEST_ENV
Special: Y
@ -29,7 +89,7 @@ test environment:
test environment detail: |-
PC has 1 wired NIC connected to AP.
1 8089 tablet able to run iperf test placed near SSC1.
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_ADC
<<: *TEST_ENV
Special: Y
@ -38,14 +98,14 @@ test environment:
PC has 1 wired NIC connected to AP.
Analog input connect to SSC1 TOUT.
Multimeter connect to input, able to measure input voltage.
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_AMSDU
<<: *TEST_ENV
Special: Y
Target Count: 1
test environment detail: |-
1 SSC target connect PC by UART.
PC 无线网卡和 SSC target 均连接到天猫魔盒AP.
1 SSC DUT connect PC by UART.
PC 无线网卡和 SSC DUT 均连接到天猫魔盒AP.
- tag: SSC_T1_APC
<<: *TEST_ENV
Special: Y
@ -55,12 +115,12 @@ test environment:
PC has 1 wired NIC connected to APC (static IP within the same subnet with APC).
APC control AP power supply.
PC has 1 WiFi NIC.
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_Enterprise
<<: *TEST_ENV
Special: Y
Target Count: 1
test environment detail: "AP use WPA2-Etherprise is placed near SSC1. \n1 SSC target
test environment detail: "AP use WPA2-Etherprise is placed near SSC1. \n1 SSC DUT
connect with PC by UART."
- tag: SSC_T1_IOT1
<<: *TEST_ENV
@ -68,14 +128,14 @@ test environment:
Target Count: 1
test environment detail: |-
PC has 1 WiFi NIC.
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
AP todo IOT test are placed near SSC1.
- tag: SSC_T1_InitData
<<: *TEST_ENV
Special: Y
Target Count: 2
test environment detail: |-
2 SSC target connect with PC by UART.
2 SSC DUT connect with PC by UART.
SSC1 use 40M crystal oscillator.
SSC2 use normal 26M crystal oscillator.
SSC2 GPIO connect to SSC1 power control pin.
@ -83,7 +143,7 @@ test environment:
<<: *TEST_ENV
Special: N
Target Count: 1
test environment detail: 1 SSC target connect with PC by UART. All APs power on.
test environment detail: 1 SSC DUT connect with PC by UART. All APs power on.
- tag: SSC_T1_ShieldBox
<<: *TEST_ENV
Special: Y
@ -98,8 +158,8 @@ test environment:
Special: Y
Target Count: 1
test environment detail: |-
AP support DTIM placed with AT target.
SSC target connect with Raspberry Pi by UART.
AP support DTIM placed with AT DUT.
SSC DUT connect with Raspberry Pi by UART.
Multimeter connect with Raspberry Pi via GPIB.
Series multimeter between GND and VCC of SSC1.
SSC1's light sleep wakeup pin and wakeup indication connect with Raspberry Pi's GPIO.
@ -109,8 +169,8 @@ test environment:
Special: Y
Target Count: 1
test environment detail: |-
AP support DTIM placed with AT target.
SSC target connect with Raspberry Pi by UART.
AP support DTIM placed with AT DUT.
SSC DUT connect with Raspberry Pi by UART.
Multimeter connect with Raspberry Pi via GPIB.
Series multimeter between GND and VCC of SSC1.
SSC1's RSTB pin connect with Raspberry Pi's GPIO.
@ -119,8 +179,8 @@ test environment:
Special: Y
Target Count: 1
test environment detail: |-
AP support DTIM placed with AT target.
SSC target connect with Raspberry Pi by UART.
AP support DTIM placed with AT DUT.
SSC DUT connect with Raspberry Pi by UART.
Multimeter connect with Raspberry Pi via GPIB.
Series multimeter between GND and VCC of SSC1.
- tag: SSC_T1_Sniffer
@ -128,26 +188,26 @@ test environment:
Target Count: 1
test environment detail: |-
PC has 1 wired NIC connected to AP. PC has 1 WiFi NIC.
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
- tag: SSC_T1_TempBox
<<: *TEST_ENV
Special: Y
Target Count: 1
test environment detail: |-
1 SSC target connect with PC by UART.
Put SSC target to temperature box.
1 SSC DUT connect with PC by UART.
Put SSC DUT to temperature box.
- tag: SSC_T1_VDD33
<<: *TEST_ENV
Special: Y
Target Count: 1
test environment detail: |-
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
Multimeter connect to VDD33, able to measure voltage.
- tag: SSC_T1_WEP
<<: *TEST_ENV
Target Count: 1
test environment detail: |-
1 SSC target connect with PC by UART.
1 SSC DUT connect with PC by UART.
One WEP share key AP placed near SSC1.
- tag: SSC_T2_1
<<: *TEST_ENV
@ -155,29 +215,53 @@ test environment:
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
2 SSC target connect with PC by UART.
2 SSC DUTs connect with PC by UART.
- tag: SSC_T2_2
<<: *TEST_ENV
Target Count: 2
test environment detail: |-
PC has 1 WiFi NIC.
2 SSC DUTs connect with PC by UART.
- tag: SSC_T2_3
<<: *TEST_ENV
Target Count: 2
test environment detail: |-
2 SSC DUTs connect with PC by UART.
AP placed near SSC DUTs
- tag: SSC_T2_4
<<: *TEST_ENV
Target Count: 2
test environment detail: |-
PC has 1 wired NIC connected to AP.
AP placed near SSC DUTs and PC.
2 SSC DUTs connect with PC by UART.
- tag: SSC_T2_5
<<: *TEST_ENV
Target Count: 2
test environment detail: |-
2 SSC DUTs connect with PC by UART.
- tag: SSC_T2_JAP
<<: *TEST_ENV
Target Count: 2
test environment detail: |-
PC has 1 wired NIC connected to APC.
APC control the power supply of multiple APs.
2 SSC target connect with PC by UART.
2 SSC DUT connect with PC by UART.
- tag: SSC_T2_PhyMode
<<: *TEST_ENV
PC OS: 'linux'
Target Count: 2
test environment detail: |-
2 SSC target connect with PC by UART.
2 SSC DUT connect with PC by UART.
PC has one WiFi NIC support capture wlan packet using libpcap.
Set 4 AP with phy mode 11b, 11g, 11n HT20, 11n HT40.
Put 4 APs near SSC targets.
Put 4 APs near SSC DUTs.
- tag: SSC_T2_ShieldBox
<<: *TEST_ENV
Special: Y
Target Count: 2
test environment detail: |-
2 SSC target connect with PC by UART.
2 SSC DUT connect with PC by UART.
Put them to Shield box.
- tag: SSC_T2_ShieldBox2
<<: *TEST_ENV
@ -185,7 +269,7 @@ test environment:
Target Count: 1
test environment detail: |
refer to figure.
2 SSC target connect with PC by UART. Put target board to different Shield boxes.
2 SSC DUT connect with PC by UART. Put DUT board to different Shield boxes.
2 shield boxes are connected with programmable attenuator.
- tag: SSC_T2_Sniffer
<<: *TEST_ENV
@ -195,14 +279,14 @@ test environment:
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
2 SSC target connect with PC by UART.
2 SSC DUT connect with PC by UART.
- tag: SSC_T2_TempBox
<<: *TEST_ENV
Special: Y
Target Count: 1
test environment detail: |
refer to figure.
2 SSC target connect with PC by UART. Put 1 target board to temperature box.
2 SSC DUT connect with PC by UART. Put 1 DUT board to temperature box.
- tag: SSC_T3_1
<<: *TEST_ENV
Special: N
@ -210,34 +294,64 @@ test environment:
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
3 SSC target connect with PC by UART.
3 SSC DUT connect with PC by UART.
- tag: SSC_T3_PhyMode
<<: *TEST_ENV
PC OS: 'linux'
Target Count: 3
test environment detail: |-
3 SSC target connect with PC by UART.
3 SSC DUT connect with PC by UART.
PC has one WiFi NIC support capture wlan packet using libpcap.
Set 4 AP with (HT20, channel1), (HT20, channel2), (HT40, channel1), (HT40, channel2).
Put 4 APs near SSC targets.
Put 4 APs near SSC DUTs.
- tag: SSC_T5_1
<<: *TEST_ENV
Target Count: 5
test environment detail: 5 SSC target connect with PC by UART.
test environment detail: 5 SSC DUT connect with PC by UART.
- tag: SSC_T5_IOT1
<<: *TEST_ENV
Special: Y
Target Count: 5
test environment detail: |-
5 SSC targets connect with PC by UART.
some Android smart phone are placed near SSC targets.
5 SSC DUTs connect with PC by UART.
some Android smart phone are placed near SSC DUTs.
- tag: SSC_T6_1
<<: *TEST_ENV
Target Count: 1
Special: Y
Target Count: 6
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
6 SSC target connect with PC by UART.
6 SSC DUT connect with PC by UART.
- tag: SSC_T1_DNS
<<: *TEST_ENV
Target Count: 1
test environment detail: 1 SSC DUT connect with PC by UART,AP should Access to the Internet.
- tag: SSC_T1_SmartConfigIOT
<<: *TEST_ENV
Special: Y
Target Count: 1
test environment detail: |
1 SSC DUT connect with PC by UART.
PC has 1 wired NIC connect to Common AP.
Several AP are placed near AT DUT.
Several smart phone installed test APK are placed near SSC DUT.
- tag: SSC_T20_1
<<: *TEST_ENV
Special: Y
Target Count: 20
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
20 SSC DUT connect with PC by UART.
- tag: SSC_T35_1
<<: *TEST_ENV
Special: Y
Target Count: 35
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
37 SSC DUT connect with PC by UART.
- tag: SSC_T50_1
<<: *TEST_ENV
Special: Y
@ -245,4 +359,28 @@ test environment:
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
50 SSC target connect with PC by UART.
50 SSC DUT connect with PC by UART.
- tag: SSC_T60_1
<<: *TEST_ENV
Special: Y
Target Count: 60
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
60 SSC DUT connect with PC by UART.
- tag: SSC_T80_1
<<: *TEST_ENV
Special: Y
Target Count: 80
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
80 SSC DUT connect with PC by UART.
- tag: SSC_T100_1
<<: *TEST_ENV
Special: Y
Target Count: 100
test environment detail: |-
PC has 1 wired NIC connected to AP.
PC has 1 WiFi NIC.
100 SSC DUT connect with PC by UART.

View file

@ -1,41 +1,37 @@
set(COMPONENT_ADD_INCLUDEDIRS
include/lwip
include/lwip/port
include/lwip/posix
apps/ping
include/apps
lwip/src/include
port/esp32/include
port/esp32/include/arch
)
set(COMPONENT_SRCDIRS
apps/dhcpserver
apps/ping
lwip/src/api
lwip/src/apps/sntp
lwip/src/core
lwip/src/core/ipv4
lwip/src/core/ipv6
lwip/src/netif
lwip/src/netif/ppp
port/esp32
port/esp32/freertos
port/esp32/netif
port/esp32/debug
)
if(CONFIG_PPP_SUPPORT)
set(LWIP_PPP_DIRS netif/ppp/polarssl netif/ppp)
list(APPEND COMPONENT_SRCDIRS
lwip/src/netif/ppp
lwip/src/netif/ppp/polarssl
)
endif()
set(COMPONENT_SRCDIRS
api
apps apps/sntp apps/ping
core core/ipv4 core/ipv6
${LWIP_PPP_DIRS} netif
port/freertos port/netif port/debug port)
set(COMPONENT_REQUIRES vfs)
set(COMPONENT_PRIV_REQUIRES ethernet tcpip_adapter)
register_component()
# lots of LWIP source files evaluate macros that check address of stack variables
component_compile_options(-Wno-address)
# patch around warnings in third-party files
set_source_files_properties(api/tcpip.c
PROPERTIES COMPILE_FLAGS
-Wno-unused-variable
)
set_source_files_properties(core/pbuf.c core/tcp_in.c
PROPERTIES COMPILE_FLAGS
-Wno-unused-but-set-variable
)
set_source_files_properties(apps/dhcpserver.c
PROPERTIES COMPILE_FLAGS
"-Wno-unused-variable -Wno-unused-but-set-variable -Wno-type-limits"
)
set_source_files_properties(netif/ppp/pppos.c
PROPERTIES COMPILE_FLAGS
-Wno-type-limits)

View file

@ -1,33 +0,0 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/

View file

@ -1,86 +0,0 @@
INTRODUCTION
lwIP is a small independent implementation of the TCP/IP protocol
suite that has been developed by Adam Dunkels at the Computer and
Networks Architectures (CNA) lab at the Swedish Institute of Computer
Science (SICS).
The focus of the lwIP TCP/IP implementation is to reduce the RAM usage
while still having a full scale TCP. This making lwIP suitable for use
in embedded systems with tens of kilobytes of free RAM and room for
around 40 kilobytes of code ROM.
FEATURES
* IP (Internet Protocol) including packet forwarding over multiple network
interfaces
* ICMP (Internet Control Message Protocol) for network maintenance and debugging
* IGMP (Internet Group Management Protocol) for multicast traffic management
* UDP (User Datagram Protocol) including experimental UDP-lite extensions
* TCP (Transmission Control Protocol) with congestion control, RTT estimation
and fast recovery/fast retransmit
* Specialized raw/native API for enhanced performance
* Optional Berkeley-like socket API
* DNS (Domain names resolver)
* SNMP (Simple Network Management Protocol)
* DHCP (Dynamic Host Configuration Protocol)
* AUTOIP (for IPv4, conform with RFC 3927)
* PPP (Point-to-Point Protocol)
* ARP (Address Resolution Protocol) for Ethernet
LICENSE
lwIP is freely available under a BSD license.
DEVELOPMENT
lwIP has grown into an excellent TCP/IP stack for embedded devices,
and developers using the stack often submit bug fixes, improvements,
and additions to the stack to further increase its usefulness.
Development of lwIP is hosted on Savannah, a central point for
software development, maintenance and distribution. Everyone can
help improve lwIP by use of Savannah's interface, Git and the
mailing list. A core team of developers will commit changes to the
Git source tree.
The lwIP TCP/IP stack is maintained in the 'lwip' Git module and
contributions (such as platform ports) are in the 'contrib' Git module.
See doc/savannah.txt for details on Git server access for users and
developers.
The current Git trees are web-browsable:
http://git.savannah.gnu.org/cgit/lwip.git
http://git.savannah.gnu.org/cgit/lwip/lwip-contrib.git
Submit patches and bugs via the lwIP project page:
http://savannah.nongnu.org/projects/lwip/
DOCUMENTATION
The original out-dated homepage of lwIP and Adam Dunkels' papers on
lwIP are at the official lwIP home page:
http://www.sics.se/~adam/lwip/
Self documentation of the source code is regularly extracted from the
current Git sources and is available from this web page:
http://www.nongnu.org/lwip/
There is now a constantly growin wiki about lwIP at
http://lwip.wikia.com/wiki/LwIP_Wiki
Also, there are mailing lists you can subscribe at
http://savannah.nongnu.org/mail/?group=lwip
plus searchable archives:
http://lists.nongnu.org/archive/html/lwip-users/
http://lists.nongnu.org/archive/html/lwip-devel/
Reading Adam's papers, the files in docs/, browsing the source code
documentation and browsing the mailing list archives is a good way to
become familiar with the design of lwIP.
Adam Dunkels <adam@sics.se>
Leon Woestenberg <leon.woestenberg@gmx.net>

View file

@ -1,984 +0,0 @@
/**
* @file
* Sequential API External module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* This is the part of the API that is linked with
the application */
#include "lwip/opt.h"
#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
#include "lwip/api.h"
#include "lwip/memp.h"
#include "lwip/ip.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/priv/api_msg.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/priv/tcpip_priv.h"
#include <string.h>
#define API_MSG_VAR_REF(name) API_VAR_REF(name)
#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name)
#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name)
#define API_MSG_VAR_ALLOC_DONTFAIL(name) API_VAR_ALLOC_DONTFAIL(struct api_msg, MEMP_API_MSG, name)
#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name)
static err_t netconn_close_shutdown(struct netconn *conn, u8_t how);
#if !LWIP_TCPIP_CORE_LOCKING
/**
* Call the lower part of a netconn_* function
* This function is then running in the thread context
* of tcpip_thread and has exclusive access to lwIP core code.
*
* @param apimsg a struct containing the function to call and its parameters
* @return ERR_OK if the function was called, another err_t if not
*/
static err_t ESP_IRAM_ATTR
tcpip_apimsg(struct api_msg *apimsg)
{
#if LWIP_DEBUG
/* catch functions that don't set err */
apimsg->msg.err = ERR_VAL;
#endif
#if LWIP_NETCONN_SEM_PER_THREAD
apimsg->msg.op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
LWIP_ASSERT("netconn semaphore not initialized",
sys_sem_valid(apimsg->msg.op_completed_sem));
#endif
if (tcpip_send_api_msg(apimsg->function, &apimsg->msg, LWIP_API_MSG_SEM(&apimsg->msg)) == ERR_OK) {
return apimsg->msg.err;
}
return ERR_VAL;
}
#endif /* !LWIP_TCPIP_CORE_LOCKING */
/**
* Create a new netconn (of a specific type) that has a callback function.
* The corresponding pcb is also created.
*
* @param t the type of 'connection' to create (@see enum netconn_type)
* @param proto the IP protocol for RAW IP pcbs
* @param callback a function to call on status changes (RX available, TX'ed)
* @return a newly allocated struct netconn or
* NULL on memory error
*/
struct netconn*
netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
{
struct netconn *conn;
API_MSG_VAR_DECLARE(msg);
conn = netconn_alloc(t, callback);
if (conn != NULL) {
err_t err;
API_MSG_VAR_ALLOC_DONTFAIL(msg);
API_MSG_VAR_REF(msg).msg.msg.n.proto = proto;
API_MSG_VAR_REF(msg).msg.conn = conn;
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_newconn, err);
API_MSG_VAR_FREE(msg);
if (err != ERR_OK) {
LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
#if LWIP_TCP
LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
#endif /* LWIP_TCP */
#if !LWIP_NETCONN_SEM_PER_THREAD
LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
sys_sem_free(&conn->op_completed);
#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
sys_mbox_free(&conn->recvmbox);
memp_free(MEMP_NETCONN, conn);
return NULL;
}
}
return conn;
}
static inline bool is_created_by_socket(struct netconn *conn)
{
#if LWIP_SOCKET
if (conn && (conn->socket >= 0)) {
return true;
}
#endif
return false;
}
/**
* Close a netconn 'connection' and free its resources.
* UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate
* after this returns.
*
* @param conn the netconn to delete
* @return ERR_OK if the connection was deleted
*/
err_t
netconn_delete(struct netconn *conn)
{
err_t err;
API_MSG_VAR_DECLARE(msg);
/* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
if (conn == NULL) {
return ERR_OK;
}
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
/* get the time we started, which is later compared to
sys_now() + conn->send_timeout */
API_MSG_VAR_REF(msg).msg.msg.sd.time_started = sys_now();
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
#if LWIP_TCP
API_MSG_VAR_REF(msg).msg.msg.sd.polls_left =
((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
#endif /* LWIP_TCP */
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_delconn, err);
API_MSG_VAR_FREE(msg);
if (err != ERR_OK) {
return err;
}
#if ESP_THREAD_SAFE
if (is_created_by_socket(conn) == false) {
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("netconn_delete - free conn\n"));
netconn_free(conn);
}
#else
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("netconn_delete - free conn\n"));
netconn_free(conn);
#endif
return ERR_OK;
}
/**
* Get the local or remote IP address and port of a netconn.
* For RAW netconns, this returns the protocol instead of a port!
*
* @param conn the netconn to query
* @param addr a pointer to which to save the IP address
* @param port a pointer to which to save the port (or protocol for RAW)
* @param local 1 to get the local IP address, 0 to get the remote one
* @return ERR_CONN for invalid connections
* ERR_OK if the information was retrieved
*/
err_t
netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.ad.local = local;
#if LWIP_MPU_COMPATIBLE
TCPIP_APIMSG(msg, lwip_netconn_do_getaddr, err);
*addr = msg->msg.msg.ad.ipaddr;
*port = msg->msg.msg.ad.port;
#else /* LWIP_MPU_COMPATIBLE */
msg.msg.msg.ad.ipaddr = addr;
msg.msg.msg.ad.port = port;
TCPIP_APIMSG(&msg, lwip_netconn_do_getaddr, err);
#endif /* LWIP_MPU_COMPATIBLE */
API_MSG_VAR_FREE(msg);
return err;
}
/**
* Bind a netconn to a specific local IP address and port.
* Binding one netconn twice might not always be checked correctly!
*
* @param conn the netconn to bind
* @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY
* to bind to all addresses)
* @param port the local port to bind the netconn to (not used for RAW)
* @return ERR_OK if bound, any other err_t on failure
*/
err_t
netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
/* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
if (addr == NULL) {
addr = IP_ADDR_ANY;
}
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr);
API_MSG_VAR_REF(msg).msg.msg.bc.port = port;
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_bind, err);
API_MSG_VAR_FREE(msg);
return err;
}
/**
* Connect a netconn to a specific remote IP address and port.
*
* @param conn the netconn to connect
* @param addr the remote IP address to connect to
* @param port the remote port to connect to (no used for RAW)
* @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise
*/
err_t
netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
/* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
if (addr == NULL) {
addr = IP_ADDR_ANY;
}
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr);
API_MSG_VAR_REF(msg).msg.msg.bc.port = port;
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_connect, err);
API_MSG_VAR_FREE(msg);
return err;
}
/**
* Disconnect a netconn from its current peer (only valid for UDP netconns).
*
* @param conn the netconn to disconnect
* @return TODO: return value is not set here...
*/
err_t
netconn_disconnect(struct netconn *conn)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_disconnect, err);
API_MSG_VAR_FREE(msg);
return err;
}
/**
* Set a TCP netconn into listen mode
*
* @param conn the tcp netconn to set to listen mode
* @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1
* @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
* don't return any error (yet?))
*/
err_t
netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
{
#if LWIP_TCP
API_MSG_VAR_DECLARE(msg);
err_t err;
/* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
LWIP_UNUSED_ARG(backlog);
LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
#if TCP_LISTEN_BACKLOG
API_MSG_VAR_REF(msg).msg.msg.lb.backlog = backlog;
#endif /* TCP_LISTEN_BACKLOG */
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_listen, err);
API_MSG_VAR_FREE(msg);
return err;
#else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(backlog);
return ERR_ARG;
#endif /* LWIP_TCP */
}
/**
* Accept a new connection on a TCP listening netconn.
*
* @param conn the TCP listen netconn
* @param new_conn pointer where the new connection is stored
* @return ERR_OK if a new connection has been received or an error
* code otherwise
*/
err_t
netconn_accept(struct netconn *conn, struct netconn **new_conn)
{
#if LWIP_TCP
struct netconn *newconn;
err_t err;
#if TCP_LISTEN_BACKLOG
API_MSG_VAR_DECLARE(msg);
#endif /* TCP_LISTEN_BACKLOG */
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
*new_conn = NULL;
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;);
err = conn->last_err;
if (ERR_IS_FATAL(err)) {
/* don't recv on fatal errors: this might block the application task
waiting on acceptmbox forever! */
return err;
}
#if LWIP_SO_RCVTIMEO
if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
return ERR_TIMEOUT;
}
#else
sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0);
#endif /* LWIP_SO_RCVTIMEO*/
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
if (newconn == NULL) {
/* connection has been aborted */
/* in this special case, we set the netconn error from application thread, as
on a ready-to-accept listening netconn, there should not be anything running
in tcpip_thread */
NETCONN_SET_SAFE_ERR(conn, ERR_ABRT);
return ERR_ABRT;
}
#if TCP_LISTEN_BACKLOG
/* Let the stack know that we have accepted the connection. */
API_MSG_VAR_ALLOC_DONTFAIL(msg);
API_MSG_VAR_REF(msg).msg.conn = newconn;
/* don't care for the return value of lwip_netconn_do_accepted */
TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_accepted);
API_MSG_VAR_FREE(msg);
#endif /* TCP_LISTEN_BACKLOG */
*new_conn = newconn;
/* don't set conn->last_err: it's only ERR_OK, anyway */
return ERR_OK;
#else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(new_conn);
return ERR_ARG;
#endif /* LWIP_TCP */
}
/**
* Receive data: actual implementation that doesn't care whether pbuf or netbuf
* is received
*
* @param conn the netconn from which to receive data
* @param new_buf pointer where a new pbuf/netbuf is stored when received data
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
*/
static err_t ESP_IRAM_ATTR
netconn_recv_data(struct netconn *conn, void **new_buf)
{
void *buf = NULL;
u16_t len;
err_t err;
#if LWIP_TCP
API_MSG_VAR_DECLARE(msg);
#endif /* LWIP_TCP */
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
*new_buf = NULL;
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
#if LWIP_TCP
#if (LWIP_UDP || LWIP_RAW)
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
#endif /* (LWIP_UDP || LWIP_RAW) */
{
if (!sys_mbox_valid(&conn->recvmbox)) {
/* This happens when calling this function after receiving FIN */
return sys_mbox_valid(&conn->acceptmbox) ? ERR_CONN : ERR_CLSD;
}
}
#endif /* LWIP_TCP */
LWIP_ERROR("netconn_recv: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
err = conn->last_err;
if (ERR_IS_FATAL(err)) {
/* don't recv on fatal errors: this might block the application task
waiting on recvmbox forever! */
/* @todo: this does not allow us to fetch data that has been put into recvmbox
before the fatal error occurred - is that a problem? */
return err;
}
#if LWIP_SO_RCVTIMEO
if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
return ERR_TIMEOUT;
}
#else
sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
#endif /* LWIP_SO_RCVTIMEO*/
#if LWIP_TCP
#if (LWIP_UDP || LWIP_RAW)
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
#endif /* (LWIP_UDP || LWIP_RAW) */
{
if (!netconn_get_noautorecved(conn) || (buf == NULL)) {
/* Let the stack know that we have taken the data. */
/* TODO: Speedup: Don't block and wait for the answer here
(to prevent multiple thread-switches). */
API_MSG_VAR_ALLOC_DONTFAIL(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
if (buf != NULL) {
API_MSG_VAR_REF(msg).msg.msg.r.len = ((struct pbuf *)buf)->tot_len;
} else {
API_MSG_VAR_REF(msg).msg.msg.r.len = 1;
}
/* don't care for the return value of lwip_netconn_do_recv */
TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv);
API_MSG_VAR_FREE(msg);
}
/* If we are closed, we indicate that we no longer wish to use the socket */
if (buf == NULL) {
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
/* Don' store ERR_CLSD as conn->err since we are only half-closed */
return ERR_CLSD;
}
len = ((struct pbuf *)buf)->tot_len;
}
#endif /* LWIP_TCP */
#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
else
#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
#if (LWIP_UDP || LWIP_RAW)
{
#if ESP_THREAD_SAFE
if (buf == NULL){
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
return ERR_CLSD;
}
#endif
LWIP_ASSERT("buf != NULL", buf != NULL);
len = netbuf_len((struct netbuf *)buf);
}
#endif /* (LWIP_UDP || LWIP_RAW) */
#if ESP_PERF
if (len > DBG_PERF_FILTER_LEN) {
DBG_PERF_PATH_SET(DBG_PERF_DIR_RX, DBG_PERF_POINT_SOC_IN);
}
#endif
#if LWIP_SO_RCVBUF
SYS_ARCH_DEC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
/* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
*new_buf = buf;
/* don't set conn->last_err: it's only ERR_OK, anyway */
return ERR_OK;
}
/**
* Receive data (in form of a pbuf) from a TCP netconn
*
* @param conn the netconn from which to receive data
* @param new_buf pointer where a new pbuf is stored when received data
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
* ERR_ARG if conn is not a TCP netconn
*/
err_t
netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
{
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) &&
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
return netconn_recv_data(conn, (void **)new_buf);
}
/**
* Receive data (in form of a netbuf containing a packet buffer) from a netconn
*
* @param conn the netconn from which to receive data
* @param new_buf pointer where a new netbuf is stored when received data
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
*/
err_t ESP_IRAM_ATTR
netconn_recv(struct netconn *conn, struct netbuf **new_buf)
{
#if LWIP_TCP
struct netbuf *buf = NULL;
err_t err;
#endif /* LWIP_TCP */
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
*new_buf = NULL;
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
#if LWIP_TCP
#if (LWIP_UDP || LWIP_RAW)
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
#endif /* (LWIP_UDP || LWIP_RAW) */
{
struct pbuf *p = NULL;
/* This is not a listening netconn, since recvmbox is set */
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
if (buf == NULL) {
return ERR_MEM;
}
err = netconn_recv_data(conn, (void **)&p);
if (err != ERR_OK) {
memp_free(MEMP_NETBUF, buf);
return err;
}
LWIP_ASSERT("p != NULL", p != NULL);
buf->p = p;
buf->ptr = p;
buf->port = 0;
ip_addr_set_zero(&buf->addr);
*new_buf = buf;
/* don't set conn->last_err: it's only ERR_OK, anyway */
return ERR_OK;
}
#endif /* LWIP_TCP */
#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
else
#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
{
#if (LWIP_UDP || LWIP_RAW)
return netconn_recv_data(conn, (void **)new_buf);
#endif /* (LWIP_UDP || LWIP_RAW) */
}
}
/**
* TCP: update the receive window: by calling this, the application
* tells the stack that it has processed data and is able to accept
* new data.
* ATTENTION: use with care, this is mainly used for sockets!
* Can only be used when calling netconn_set_noautorecved(conn, 1) before.
*
* @param conn the netconn for which to update the receive window
* @param length amount of data processed (ATTENTION: this must be accurate!)
*/
void
netconn_recved(struct netconn *conn, u32_t length)
{
#if LWIP_TCP
if ((conn != NULL) && (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) &&
(netconn_get_noautorecved(conn))) {
API_MSG_VAR_DECLARE(msg);
/* Let the stack know that we have taken the data. */
/* TODO: Speedup: Don't block and wait for the answer here
(to prevent multiple thread-switches). */
API_MSG_VAR_ALLOC_DONTFAIL(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.r.len = length;
/* don't care for the return value of lwip_netconn_do_recv */
TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv);
API_MSG_VAR_FREE(msg);
}
#else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(length);
#endif /* LWIP_TCP */
}
/**
* Send data (in form of a netbuf) to a specific remote IP address and port.
* Only to be used for UDP and RAW netconns (not TCP).
*
* @param conn the netconn over which to send data
* @param buf a netbuf containing the data to send
* @param addr the remote IP address to which to send the data
* @param port the remote port to which to send the data
* @return ERR_OK if data was sent, any other err_t on error
*/
err_t
netconn_sendto(struct netconn *conn, struct netbuf *buf, const ip_addr_t *addr, u16_t port)
{
if (buf != NULL) {
ip_addr_set(&buf->addr, addr);
buf->port = port;
return netconn_send(conn, buf);
}
return ERR_VAL;
}
/**
* Send data over a UDP or RAW netconn (that is already connected).
*
* @param conn the UDP or RAW netconn over which to send data
* @param buf a netbuf containing the data to send
* @return ERR_OK if data was sent, any other err_t on error
*/
err_t ESP_IRAM_ATTR
netconn_send(struct netconn *conn, struct netbuf *buf)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.b = buf;
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_send, err);
API_MSG_VAR_FREE(msg);
return err;
}
/**
* Send data over a TCP netconn.
*
* @param conn the TCP netconn over which to send data
* @param dataptr pointer to the application buffer that contains the data to send
* @param size size of the application data to send
* @param apiflags combination of following flags :
* - NETCONN_COPY: data will be copied into memory belonging to the stack
* - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
* - NETCONN_DONTBLOCK: only write the data if all data can be written at once
* @param bytes_written pointer to a location that receives the number of written bytes
* @return ERR_OK if data was sent, any other err_t on error
*/
err_t
netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
u8_t apiflags, size_t *bytes_written)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
u8_t dontblock;
LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type)== NETCONN_TCP), return ERR_VAL;);
if (size == 0) {
return ERR_OK;
}
dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
if (dontblock && !bytes_written) {
/* This implies netconn_write() cannot be used for non-blocking send, since
it has no way to return the number of bytes written. */
return ERR_VAL;
}
API_MSG_VAR_ALLOC(msg);
/* non-blocking write sends as much */
API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.w.dataptr = dataptr;
API_MSG_VAR_REF(msg).msg.msg.w.apiflags = apiflags;
API_MSG_VAR_REF(msg).msg.msg.w.len = size;
#if LWIP_SO_SNDTIMEO
if (conn->send_timeout != 0) {
/* get the time we started, which is later compared to
sys_now() + conn->send_timeout */
API_MSG_VAR_REF(msg).msg.msg.w.time_started = sys_now();
} else {
API_MSG_VAR_REF(msg).msg.msg.w.time_started = 0;
}
#endif /* LWIP_SO_SNDTIMEO */
/* For locking the core: this _can_ be delayed on low memory/low send buffer,
but if it is, this is done inside api_msg.c:do_write(), so we can use the
non-blocking version here. */
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_write, err);
if ((err == ERR_OK) && (bytes_written != NULL)) {
if (dontblock
#if LWIP_SO_SNDTIMEO
|| (conn->send_timeout != 0)
#endif /* LWIP_SO_SNDTIMEO */
) {
/* nonblocking write: maybe the data has been sent partly */
*bytes_written = API_MSG_VAR_REF(msg).msg.msg.w.len;
} else {
/* blocking call succeeded: all data has been sent if it */
*bytes_written = size;
}
}
API_MSG_VAR_FREE(msg);
return err;
}
/**
* Close or shutdown a TCP netconn (doesn't delete it).
*
* @param conn the TCP netconn to close or shutdown
* @param how fully close or only shutdown one side?
* @return ERR_OK if the netconn was closed, any other err_t on error
*/
static err_t
netconn_close_shutdown(struct netconn *conn, u8_t how)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
LWIP_UNUSED_ARG(how);
LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).msg.conn = conn;
#if LWIP_TCP
/* shutting down both ends is the same as closing */
API_MSG_VAR_REF(msg).msg.msg.sd.shut = how;
#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
/* get the time we started, which is later compared to
sys_now() + conn->send_timeout */
API_MSG_VAR_REF(msg).msg.msg.sd.time_started = sys_now();
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
API_MSG_VAR_REF(msg).msg.msg.sd.polls_left =
((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
#endif /* LWIP_TCP */
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_close, err);
API_MSG_VAR_FREE(msg);
return err;
}
/**
* Close a TCP netconn (doesn't delete it).
*
* @param conn the TCP netconn to close
* @return ERR_OK if the netconn was closed, any other err_t on error
*/
err_t
netconn_close(struct netconn *conn)
{
/* shutting down both ends is the same as closing */
return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
}
/**
* Shut down one or both sides of a TCP netconn (doesn't delete it).
*
* @param conn the TCP netconn to shut down
* @return ERR_OK if the netconn was closed, any other err_t on error
*/
err_t
netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
{
return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0));
}
#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
/**
* Join multicast groups for UDP netconns.
*
* @param conn the UDP netconn for which to change multicast addresses
* @param multiaddr IP address of the multicast group to join or leave
* @param netif_addr the IP address of the network interface on which to send
* the igmp message
* @param join_or_leave flag whether to send a join- or leave-message
* @return ERR_OK if the action was taken, any err_t on error
*/
err_t
netconn_join_leave_group(struct netconn *conn,
const ip_addr_t *multiaddr,
const ip_addr_t *netif_addr,
enum netconn_igmp join_or_leave)
{
API_MSG_VAR_DECLARE(msg);
err_t err;
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg);
/* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
if (multiaddr == NULL) {
multiaddr = IP_ADDR_ANY;
}
if (netif_addr == NULL) {
netif_addr = IP_ADDR_ANY;
}
API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr);
API_MSG_VAR_REF(msg).msg.msg.jl.netif_addr = API_MSG_VAR_REF(netif_addr);
API_MSG_VAR_REF(msg).msg.msg.jl.join_or_leave = join_or_leave;
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_join_leave_group, err);
API_MSG_VAR_FREE(msg);
return err;
}
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
#if LWIP_DNS
/**
* Execute a DNS query, only one IP address is returned
*
* @param name a string representation of the DNS host name to query
* @param addr a preallocated ip_addr_t where to store the resolved IP address
* @return ERR_OK: resolving succeeded
* ERR_MEM: memory error, try again later
* ERR_ARG: dns client not initialized or invalid hostname
* ERR_VAL: dns server response was invalid
*/
#if LWIP_IPV4 && LWIP_IPV6
err_t
netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype)
#else
err_t
netconn_gethostbyname(const char *name, ip_addr_t *addr)
#endif
{
API_VAR_DECLARE(struct dns_api_msg, msg);
err_t localerr;
#if !LWIP_MPU_COMPATIBLE
sys_sem_t sem;
#endif /* LWIP_MPU_COMPATIBLE */
err_t err = ERR_OK;
LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
#if LWIP_MPU_COMPATIBLE
if (strlen(name) >= DNS_MAX_NAME_LENGTH) {
return ERR_ARG;
}
#endif
API_VAR_ALLOC(struct dns_api_msg, MEMP_DNS_API_MSG, msg);
#if LWIP_MPU_COMPATIBLE
strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH-1);
API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH-1] = 0;
#else /* LWIP_MPU_COMPATIBLE */
msg.err = &err;
msg.sem = &sem;
API_VAR_REF(msg).addr = API_VAR_REF(addr);
API_VAR_REF(msg).name = name;
#endif /* LWIP_MPU_COMPATIBLE */
#if LWIP_IPV4 && LWIP_IPV6
API_VAR_REF(msg).dns_addrtype = dns_addrtype;
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#if LWIP_NETCONN_SEM_PER_THREAD
API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET();
#else /* LWIP_NETCONN_SEM_PER_THREAD*/
err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0);
if (err != ERR_OK) {
API_VAR_FREE(MEMP_DNS_API_MSG, msg);
return err;
}
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
localerr = tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg));
if (localerr != ERR_OK) {
#if !LWIP_NETCONN_SEM_PER_THREAD
sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem));
#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
API_VAR_FREE(MEMP_DNS_API_MSG, msg);
return localerr;
}
sys_sem_wait(API_EXPR_REF_SEM(API_VAR_REF(msg).sem));
#if !LWIP_NETCONN_SEM_PER_THREAD
sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem));
#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
#if LWIP_MPU_COMPATIBLE
*addr = msg->addr;
err = msg->err;
#endif /* LWIP_MPU_COMPATIBLE */
API_VAR_FREE(MEMP_DNS_API_MSG, msg);
return err;
}
#endif /* LWIP_DNS*/
#if LWIP_NETCONN_SEM_PER_THREAD
void
netconn_thread_init(void)
{
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
if ((sem == NULL) || !sys_sem_valid(sem)) {
/* call alloc only once */
LWIP_NETCONN_THREAD_SEM_ALLOC();
LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET()));
}
}
void
netconn_thread_cleanup(void)
{
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
if ((sem != NULL) && sys_sem_valid(sem)) {
/* call free only once */
LWIP_NETCONN_THREAD_SEM_FREE();
}
}
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#endif /* LWIP_NETCONN */

File diff suppressed because it is too large Load diff

View file

@ -1,75 +0,0 @@
/**
* @file
* Error Management module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/err.h"
#ifdef LWIP_DEBUG
static const char *err_strerr[] = {
"Ok.", /* ERR_OK 0 */
"Out of memory error.", /* ERR_MEM -1 */
"Buffer error.", /* ERR_BUF -2 */
"Timeout.", /* ERR_TIMEOUT -3 */
"Routing problem.", /* ERR_RTE -4 */
"Operation in progress.", /* ERR_INPROGRESS -5 */
"Illegal value.", /* ERR_VAL -6 */
"Operation would block.", /* ERR_WOULDBLOCK -7 */
"Address in use.", /* ERR_USE -8 */
"Already connecting.", /* ERR_ALREADY -9 */
"Already connected.", /* ERR_ISCONN -10 */
"Not connected.", /* ERR_CONN -11 */
"Low-level netif error.", /* ERR_IF -12 */
"Connection aborted.", /* ERR_ABRT -13 */
"Connection reset.", /* ERR_RST -14 */
"Connection closed.", /* ERR_CLSD -15 */
"Illegal argument." /* ERR_ARG -16 */
};
/**
* Convert an lwip internal error to a string representation.
*
* @param err an lwip internal err_t
* @return a string representation for err
*/
const char *
lwip_strerr(err_t err)
{
return err_strerr[-err];
}
#endif /* LWIP_DEBUG */

View file

@ -1,245 +0,0 @@
/**
* @file
* Network buffer management
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
#include "lwip/netbuf.h"
#include "lwip/memp.h"
#include <string.h>
/**
* Create (allocate) and initialize a new netbuf.
* The netbuf doesn't yet contain a packet buffer!
*
* @return a pointer to a new netbuf
* NULL on lack of memory
*/
struct
netbuf *netbuf_new(void)
{
struct netbuf *buf;
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
if (buf != NULL) {
buf->p = NULL;
buf->ptr = NULL;
ip_addr_set_zero(&buf->addr);
buf->port = 0;
#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY
#if LWIP_CHECKSUM_ON_COPY
buf->flags = 0;
#endif /* LWIP_CHECKSUM_ON_COPY */
buf->toport_chksum = 0;
#if LWIP_NETBUF_RECVINFO
ip_addr_set_zero(&buf->toaddr);
#endif /* LWIP_NETBUF_RECVINFO */
#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */
return buf;
} else {
return NULL;
}
}
/**
* Deallocate a netbuf allocated by netbuf_new().
*
* @param buf pointer to a netbuf allocated by netbuf_new()
*/
void
netbuf_delete(struct netbuf *buf)
{
if (buf != NULL) {
if (buf->p != NULL) {
pbuf_free(buf->p);
buf->p = buf->ptr = NULL;
}
memp_free(MEMP_NETBUF, buf);
}
}
/**
* Allocate memory for a packet buffer for a given netbuf.
*
* @param buf the netbuf for which to allocate a packet buffer
* @param size the size of the packet buffer to allocate
* @return pointer to the allocated memory
* NULL if no memory could be allocated
*/
void * ESP_IRAM_ATTR
netbuf_alloc(struct netbuf *buf, u16_t size)
{
LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
/* Deallocate any previously allocated memory. */
if (buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
if (buf->p == NULL) {
return NULL;
}
LWIP_ASSERT("check that first pbuf can hold size",
(buf->p->len >= size));
buf->ptr = buf->p;
return buf->p->payload;
}
/**
* Free the packet buffer included in a netbuf
*
* @param buf pointer to the netbuf which contains the packet buffer to free
*/
void ESP_IRAM_ATTR
netbuf_free(struct netbuf *buf)
{
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
if (buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = buf->ptr = NULL;
}
/**
* Let a netbuf reference existing (non-volatile) data.
*
* @param buf netbuf which should reference the data
* @param dataptr pointer to the data to reference
* @param size size of the data
* @return ERR_OK if data is referenced
* ERR_MEM if data couldn't be referenced due to lack of memory
*/
err_t
netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size)
{
LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;);
if (buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
if (buf->p == NULL) {
buf->ptr = NULL;
return ERR_MEM;
}
((struct pbuf_rom*)buf->p)->payload = dataptr;
buf->p->len = buf->p->tot_len = size;
buf->ptr = buf->p;
return ERR_OK;
}
/**
* Chain one netbuf to another (@see pbuf_chain)
*
* @param head the first netbuf
* @param tail netbuf to chain after head, freed by this function, may not be reference after returning
*/
void
netbuf_chain(struct netbuf *head, struct netbuf *tail)
{
LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;);
LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;);
pbuf_cat(head->p, tail->p);
head->ptr = head->p;
memp_free(MEMP_NETBUF, tail);
}
/**
* Get the data pointer and length of the data inside a netbuf.
*
* @param buf netbuf to get the data from
* @param dataptr pointer to a void pointer where to store the data pointer
* @param len pointer to an u16_t where the length of the data is stored
* @return ERR_OK if the information was retrieved,
* ERR_BUF on error.
*/
err_t
netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
{
LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;);
LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;);
if (buf->ptr == NULL) {
return ERR_BUF;
}
*dataptr = buf->ptr->payload;
*len = buf->ptr->len;
return ERR_OK;
}
/**
* Move the current data pointer of a packet buffer contained in a netbuf
* to the next part.
* The packet buffer itself is not modified.
*
* @param buf the netbuf to modify
* @return -1 if there is no next part
* 1 if moved to the next part but now there is no next part
* 0 if moved to the next part and there are still more parts
*/
s8_t
netbuf_next(struct netbuf *buf)
{
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;);
if (buf->ptr->next == NULL) {
return -1;
}
buf->ptr = buf->ptr->next;
if (buf->ptr->next == NULL) {
return 1;
}
return 0;
}
/**
* Move the current data pointer of a packet buffer contained in a netbuf
* to the beginning of the packet.
* The packet buffer itself is not modified.
*
* @param buf the netbuf to modify
*/
void
netbuf_first(struct netbuf *buf)
{
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
buf->ptr = buf->p;
}
#endif /* LWIP_NETCONN */

View file

@ -1,421 +0,0 @@
/**
* @file
* API functions for name resolving
*
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt
*
*/
#include "lwip/netdb.h"
#if LWIP_DNS && LWIP_SOCKET
#include "lwip/err.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/ip_addr.h"
#include "lwip/api.h"
#include "lwip/dns.h"
#include <string.h>
#include <stdlib.h>
/** helper struct for gethostbyname_r to access the char* buffer */
struct gethostbyname_r_helper {
ip_addr_t *addr_list[2];
ip_addr_t addr;
char *aliases;
};
/** h_errno is exported in netdb.h for access by applications. */
#if LWIP_DNS_API_DECLARE_H_ERRNO
int h_errno;
#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
/** define "hostent" variables storage: 0 if we use a static (but unprotected)
* set of variables for lwip_gethostbyname, 1 if we use a local storage */
#ifndef LWIP_DNS_API_HOSTENT_STORAGE
#define LWIP_DNS_API_HOSTENT_STORAGE 0
#endif
/** define "hostent" variables storage */
#if LWIP_DNS_API_HOSTENT_STORAGE
#define HOSTENT_STORAGE
#else
#define HOSTENT_STORAGE static
#endif /* LWIP_DNS_API_STATIC_HOSTENT */
/**
* Returns an entry containing addresses of address family AF_INET
* for the host with name name.
* Due to dns_gethostbyname limitations, only one address is returned.
*
* @param name the hostname to resolve
* @return an entry containing addresses of address family AF_INET
* for the host with name name
*/
struct hostent*
lwip_gethostbyname(const char *name)
{
err_t err;
ip_addr_t addr;
/* buffer variables for lwip_gethostbyname() */
HOSTENT_STORAGE struct hostent s_hostent;
HOSTENT_STORAGE char *s_aliases;
HOSTENT_STORAGE ip_addr_t s_hostent_addr;
HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2];
HOSTENT_STORAGE char s_hostname[DNS_MAX_NAME_LENGTH + 1];
/* query host IP address */
err = netconn_gethostbyname(name, &addr);
if (err != ERR_OK) {
LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
h_errno = HOST_NOT_FOUND;
return NULL;
}
/* fill hostent */
s_hostent_addr = addr;
s_phostent_addr[0] = &s_hostent_addr;
s_phostent_addr[1] = NULL;
strncpy(s_hostname, name, DNS_MAX_NAME_LENGTH);
s_hostname[DNS_MAX_NAME_LENGTH] = 0;
s_hostent.h_name = s_hostname;
s_aliases = NULL;
s_hostent.h_aliases = &s_aliases;
s_hostent.h_addrtype = AF_INET;
s_hostent.h_length = sizeof(ip_addr_t);
s_hostent.h_addr_list = (char**)&s_phostent_addr;
#if DNS_DEBUG
/* dump hostent */
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", (void*)s_hostent.h_aliases));
/* h_aliases are always empty */
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", (void*)s_hostent.h_addr_list));
if (s_hostent.h_addr_list != NULL) {
u8_t idx;
for (idx=0; s_hostent.h_addr_list[idx]; idx++) {
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx])));
}
}
#endif /* DNS_DEBUG */
#if LWIP_DNS_API_HOSTENT_STORAGE
/* this function should return the "per-thread" hostent after copy from s_hostent */
return sys_thread_hostent(&s_hostent);
#else
return &s_hostent;
#endif /* LWIP_DNS_API_HOSTENT_STORAGE */
}
/**
* Thread-safe variant of lwip_gethostbyname: instead of using a static
* buffer, this function takes buffer and errno pointers as arguments
* and uses these for the result.
*
* @param name the hostname to resolve
* @param ret pre-allocated struct where to store the result
* @param buf pre-allocated buffer where to store additional data
* @param buflen the size of buf
* @param result pointer to a hostent pointer that is set to ret on success
* and set to zero on error
* @param h_errnop pointer to an int where to store errors (instead of modifying
* the global h_errno)
* @return 0 on success, non-zero on error, additional error information
* is stored in *h_errnop instead of h_errno to be thread-safe
*/
int
lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop)
{
err_t err;
struct gethostbyname_r_helper *h;
char *hostname;
size_t namelen;
int lh_errno;
if (h_errnop == NULL) {
/* ensure h_errnop is never NULL */
h_errnop = &lh_errno;
}
if (result == NULL) {
/* not all arguments given */
*h_errnop = EINVAL;
return -1;
}
/* first thing to do: set *result to nothing */
*result = NULL;
if ((name == NULL) || (ret == NULL) || (buf == NULL)) {
/* not all arguments given */
*h_errnop = EINVAL;
return -1;
}
namelen = strlen(name);
if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
/* buf can't hold the data needed + a copy of name */
*h_errnop = ERANGE;
return -1;
}
h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
/* query host IP address */
err = netconn_gethostbyname(name, &h->addr);
if (err != ERR_OK) {
LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
*h_errnop = HOST_NOT_FOUND;
return -1;
}
/* copy the hostname into buf */
MEMCPY(hostname, name, namelen);
hostname[namelen] = 0;
/* fill hostent */
h->addr_list[0] = &h->addr;
h->addr_list[1] = NULL;
h->aliases = NULL;
ret->h_name = hostname;
ret->h_aliases = &h->aliases;
ret->h_addrtype = AF_INET;
ret->h_length = sizeof(ip_addr_t);
ret->h_addr_list = (char**)&h->addr_list;
/* set result != NULL */
*result = ret;
/* return success */
return 0;
}
/**
* Frees one or more addrinfo structures returned by getaddrinfo(), along with
* any additional storage associated with those structures. If the ai_next field
* of the structure is not null, the entire list of structures is freed.
*
* @param ai struct addrinfo to free
*/
void
lwip_freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
while (ai != NULL) {
next = ai->ai_next;
memp_free(MEMP_NETDB, ai);
ai = next;
}
}
/**
* Translates the name of a service location (for example, a host name) and/or
* a service name and returns a set of socket addresses and associated
* information to be used in creating a socket with which to address the
* specified service.
* Memory for the result is allocated internally and must be freed by calling
* lwip_freeaddrinfo()!
*
* Due to a limitation in dns_gethostbyname, only the first address of a
* host is returned.
* Also, service names are not supported (only port numbers)!
*
* @param nodename descriptive name or address string of the host
* (may be NULL -> local address)
* @param servname port number as string of NULL
* @param hints structure containing input values that set socktype and protocol
* @param res pointer to a pointer where to store the result (set to NULL on failure)
* @return 0 on success, non-zero on failure
*
* @todo: implement AI_ADDRCONFIG
*/
int
lwip_getaddrinfo(const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
err_t err;
ip_addr_t addr;
struct addrinfo *ai;
struct sockaddr_storage *sa = NULL;
int port_nr = 0;
size_t total_size;
size_t namelen = 0;
int ai_family;
if (res == NULL) {
return EAI_FAIL;
}
*res = NULL;
if ((nodename == NULL) && (servname == NULL)) {
return EAI_NONAME;
}
if (hints != NULL) {
ai_family = hints->ai_family;
if ((ai_family != AF_UNSPEC)
#if LWIP_IPV4
&& (ai_family != AF_INET)
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
&& (ai_family != AF_INET6)
#endif /* LWIP_IPV6 */
) {
return EAI_FAMILY;
}
} else {
ai_family = AF_UNSPEC;
}
if (servname != NULL) {
/* service name specified: convert to port number
* @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */
port_nr = atoi(servname);
if ((port_nr <= 0) || (port_nr > 0xffff)) {
return EAI_SERVICE;
}
}
if (nodename != NULL) {
/* service location specified, try to resolve */
if ((hints != NULL) && (hints->ai_flags & AI_NUMERICHOST)) {
/* no DNS lookup, just parse for an address string */
if (!ipaddr_aton(nodename, &addr)) {
return EAI_NONAME;
}
#if LWIP_IPV4 && LWIP_IPV6
if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) ||
(!IP_IS_V6_VAL(addr) && ai_family == AF_INET6)) {
return EAI_NONAME;
}
#endif /* LWIP_IPV4 && LWIP_IPV6 */
} else {
#if LWIP_IPV4 && LWIP_IPV6
/* AF_UNSPEC: prefer IPv4 */
u8_t type = NETCONN_DNS_IPV4_IPV6;
if (ai_family == AF_INET) {
type = NETCONN_DNS_IPV4;
} else if (ai_family == AF_INET6) {
type = NETCONN_DNS_IPV6;
if (hints->ai_flags & AI_V4MAPPED) {
type = NETCONN_DNS_IPV6_IPV4;
}
}
#endif /* LWIP_IPV4 && LWIP_IPV6 */
err = netconn_gethostbyname_addrtype(nodename, &addr, type);
if (err != ERR_OK) {
return EAI_FAIL;
}
}
} else {
/* service location specified, use loopback address */
if ((hints != NULL) && (hints->ai_flags & AI_PASSIVE)) {
ip_addr_set_any(ai_family == AF_INET6, &addr);
} else {
ip_addr_set_loopback(ai_family == AF_INET6, &addr);
}
}
#if LWIP_IPV4 && LWIP_IPV6
if (ai_family == AF_INET6 && (hints->ai_flags & AI_V4MAPPED)
&& IP_GET_TYPE(&addr) == IPADDR_TYPE_V4) {
/* Convert native V4 address to a V4-mapped IPV6 address */
ip_addr_make_ip4_mapped_ip6(&addr, &addr);
}
#endif
total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage);
if (nodename != NULL) {
namelen = strlen(nodename);
if (namelen > DNS_MAX_NAME_LENGTH) {
/* invalid name length */
return EAI_FAIL;
}
LWIP_ASSERT("namelen is too long", total_size + namelen + 1 > total_size);
total_size += namelen + 1;
}
/* If this fails, please report to lwip-devel! :-) */
LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
total_size <= NETDB_ELEM_SIZE);
ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
if (ai == NULL) {
return EAI_MEMORY;
}
memset(ai, 0, total_size);
sa = (struct sockaddr_storage *)(void*)((u8_t*)ai + sizeof(struct addrinfo));
if (IP_IS_V6_VAL(addr)) {
#if LWIP_IPV6
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)sa;
/* set up sockaddr */
inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr));
sa6->sin6_family = AF_INET6;
sa6->sin6_len = sizeof(struct sockaddr_in6);
sa6->sin6_port = htons((u16_t)port_nr);
ai->ai_family = AF_INET6;
#endif /* LWIP_IPV6 */
} else {
#if LWIP_IPV4
struct sockaddr_in *sa4 = (struct sockaddr_in*)sa;
/* set up sockaddr */
inet_addr_from_ipaddr(&sa4->sin_addr, ip_2_ip4(&addr));
sa4->sin_family = AF_INET;
sa4->sin_len = sizeof(struct sockaddr_in);
sa4->sin_port = htons((u16_t)port_nr);
ai->ai_family = AF_INET;
#endif /* LWIP_IPV4 */
}
/* set up addrinfo */
if (hints != NULL) {
/* copy socktype & protocol from hints if specified */
ai->ai_socktype = hints->ai_socktype;
ai->ai_protocol = hints->ai_protocol;
}
if (nodename != NULL) {
/* copy nodename to canonname if specified */
ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
MEMCPY(ai->ai_canonname, nodename, namelen);
ai->ai_canonname[namelen] = 0;
}
ai->ai_addrlen = sizeof(struct sockaddr_storage);
ai->ai_addr = (struct sockaddr*)sa;
*res = ai;
return 0;
}
#endif /* LWIP_DNS && LWIP_SOCKET */

View file

@ -1,206 +0,0 @@
/**
* @file
* Network Interface Sequential API module
*
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/opt.h"
#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
#include "lwip/netifapi.h"
#include "lwip/memp.h"
#include "lwip/priv/tcpip_priv.h"
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name)
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
/**
* Call netif_add() inside the tcpip_thread context.
*/
static err_t
netifapi_do_netif_add(struct tcpip_api_call *m)
{
struct netifapi_msg *msg = (struct netifapi_msg*)m;
if (!netif_add( msg->netif,
#if LWIP_IPV4
API_EXPR_REF(msg->msg.add.ipaddr),
API_EXPR_REF(msg->msg.add.netmask),
API_EXPR_REF(msg->msg.add.gw),
#endif /* LWIP_IPV4 */
msg->msg.add.state,
msg->msg.add.init,
msg->msg.add.input)) {
return ERR_IF;
} else {
return ERR_OK;
}
}
#if LWIP_IPV4
/**
* Call netif_set_addr() inside the tcpip_thread context.
*/
static err_t
netifapi_do_netif_set_addr(struct tcpip_api_call *m)
{
struct netifapi_msg *msg = (struct netifapi_msg*)m;
netif_set_addr( msg->netif,
API_EXPR_REF(msg->msg.add.ipaddr),
API_EXPR_REF(msg->msg.add.netmask),
API_EXPR_REF(msg->msg.add.gw));
return ERR_OK;
}
#endif /* LWIP_IPV4 */
/**
* Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
* tcpip_thread context.
*/
static err_t
netifapi_do_netif_common(struct tcpip_api_call *m)
{
struct netifapi_msg *msg = (struct netifapi_msg*)m;
if (msg->msg.common.errtfunc != NULL) {
return msg->msg.common.errtfunc(msg->netif);
} else {
msg->msg.common.voidfunc(msg->netif);
return ERR_OK;
}
}
/**
* Call netif_add() in a thread-safe way by running that function inside the
* tcpip_thread context.
*
* @note for params @see netif_add()
*/
err_t
netifapi_netif_add(struct netif *netif,
#if LWIP_IPV4
const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
#endif /* LWIP_IPV4 */
void *state, netif_init_fn init, netif_input_fn input)
{
err_t err;
NETIFAPI_VAR_DECLARE(msg);
NETIFAPI_VAR_ALLOC(msg);
#if LWIP_IPV4
if (ipaddr == NULL) {
ipaddr = IP4_ADDR_ANY;
}
if (netmask == NULL) {
netmask = IP4_ADDR_ANY;
}
if (gw == NULL) {
gw = IP4_ADDR_ANY;
}
#endif /* LWIP_IPV4 */
NETIFAPI_VAR_REF(msg).netif = netif;
#if LWIP_IPV4
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
#endif /* LWIP_IPV4 */
NETIFAPI_VAR_REF(msg).msg.add.state = state;
NETIFAPI_VAR_REF(msg).msg.add.init = init;
NETIFAPI_VAR_REF(msg).msg.add.input = input;
err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
NETIFAPI_VAR_FREE(msg);
return err;
}
#if LWIP_IPV4
/**
* Call netif_set_addr() in a thread-safe way by running that function inside the
* tcpip_thread context.
*
* @note for params @see netif_set_addr()
*/
err_t
netifapi_netif_set_addr(struct netif *netif,
const ip4_addr_t *ipaddr,
const ip4_addr_t *netmask,
const ip4_addr_t *gw)
{
err_t err;
NETIFAPI_VAR_DECLARE(msg);
NETIFAPI_VAR_ALLOC(msg);
if (ipaddr == NULL) {
ipaddr = IP4_ADDR_ANY;
}
if (netmask == NULL) {
netmask = IP4_ADDR_ANY;
}
if (gw == NULL) {
gw = IP4_ADDR_ANY;
}
NETIFAPI_VAR_REF(msg).netif = netif;
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
NETIFAPI_VAR_FREE(msg);
return err;
}
#endif /* LWIP_IPV4 */
/**
* call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
* way by running that function inside the tcpip_thread context.
*
* @note use only for functions where there is only "netif" parameter.
*/
err_t
netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
netifapi_errt_fn errtfunc)
{
err_t err;
NETIFAPI_VAR_DECLARE(msg);
NETIFAPI_VAR_ALLOC(msg);
NETIFAPI_VAR_REF(msg).netif = netif;
NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc;
NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc;
err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call);
NETIFAPI_VAR_FREE(msg);
return err;
}
#endif /* LWIP_NETIF_API */

View file

@ -1,371 +0,0 @@
/**
* @file
* Point To Point Protocol Sequential API module
*
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/opt.h"
#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */
#include "lwip/pppapi.h"
#include "lwip/priv/tcpip_priv.h"
#include "netif/ppp/pppoe.h"
#include "netif/ppp/pppol2tp.h"
#include "netif/ppp/pppos.h"
/**
* Call ppp_set_default() inside the tcpip_thread context.
*/
static err_t
pppapi_do_ppp_set_default(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
ppp_set_default(msg->msg.ppp);
return ERR_OK;
}
/**
* Call ppp_set_default() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
void
pppapi_set_default(ppp_pcb *pcb)
{
struct pppapi_msg msg;
msg.msg.ppp = pcb;
tcpip_api_call(pppapi_do_ppp_set_default, &msg.call);
}
/**
* Call ppp_set_auth() inside the tcpip_thread context.
*/
static err_t
pppapi_do_ppp_set_auth(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
ppp_set_auth(msg->msg.ppp, msg->msg.msg.setauth.authtype,
msg->msg.msg.setauth.user, msg->msg.msg.setauth.passwd);
return ERR_OK;
}
/**
* Call ppp_set_auth() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
void
pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd)
{
struct pppapi_msg msg;
msg.msg.ppp = pcb;
msg.msg.msg.setauth.authtype = authtype;
msg.msg.msg.setauth.user = user;
msg.msg.msg.setauth.passwd = passwd;
tcpip_api_call(pppapi_do_ppp_set_auth, &msg.call);
}
#if PPP_NOTIFY_PHASE
/**
* Call ppp_set_notify_phase_callback() inside the tcpip_thread context.
*/
static err_t
pppapi_do_ppp_set_notify_phase_callback(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
ppp_set_notify_phase_callback(msg->msg.ppp, msg->msg.msg.setnotifyphasecb.notify_phase_cb);
return ERR_OK;
}
/**
* Call ppp_set_notify_phase_callback() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
void
pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb)
{
struct pppapi_msg msg;
msg.function = pppapi_do_ppp_set_notify_phase_callback;
msg.msg.ppp = pcb;
msg.msg.msg.setnotifyphasecb.notify_phase_cb = notify_phase_cb;
tcpip_api_call(pppapi_do_ppp_set_notify_phase_callback, &msg.call);
}
#endif /* PPP_NOTIFY_PHASE */
#if PPPOS_SUPPORT
/**
* Call pppos_create() inside the tcpip_thread context.
*/
static err_t
pppapi_do_pppos_create(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)(m);
msg->msg.ppp = pppos_create(msg->msg.msg.serialcreate.pppif, msg->msg.msg.serialcreate.output_cb,
msg->msg.msg.serialcreate.link_status_cb, msg->msg.msg.serialcreate.ctx_cb);
return ERR_OK;
}
/**
* Call pppos_create() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
ppp_pcb*
pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb,
ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
{
struct pppapi_msg msg;
msg.msg.msg.serialcreate.pppif = pppif;
msg.msg.msg.serialcreate.output_cb = output_cb;
msg.msg.msg.serialcreate.link_status_cb = link_status_cb;
msg.msg.msg.serialcreate.ctx_cb = ctx_cb;
tcpip_api_call(pppapi_do_pppos_create, &msg.call);
return msg.msg.ppp;
}
#endif /* PPPOS_SUPPORT */
#if PPPOE_SUPPORT
/**
* Call pppoe_create() inside the tcpip_thread context.
*/
static err_t
pppapi_do_pppoe_create(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
msg->msg.ppp = pppoe_create(msg->msg.msg.ethernetcreate.pppif, msg->msg.msg.ethernetcreate.ethif,
msg->msg.msg.ethernetcreate.service_name, msg->msg.msg.ethernetcreate.concentrator_name,
msg->msg.msg.ethernetcreate.link_status_cb, msg->msg.msg.ethernetcreate.ctx_cb);
return ERR_OK;
}
/**
* Call pppoe_create() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
ppp_pcb*
pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name,
const char *concentrator_name, ppp_link_status_cb_fn link_status_cb,
void *ctx_cb)
{
struct pppapi_msg msg;
msg.msg.msg.ethernetcreate.pppif = pppif;
msg.msg.msg.ethernetcreate.ethif = ethif;
msg.msg.msg.ethernetcreate.service_name = service_name;
msg.msg.msg.ethernetcreate.concentrator_name = concentrator_name;
msg.msg.msg.ethernetcreate.link_status_cb = link_status_cb;
msg.msg.msg.ethernetcreate.ctx_cb = ctx_cb;
tcpip_api_call(pppapi_do_pppoe_create, &msg.call);
return msg.msg.ppp;
}
#endif /* PPPOE_SUPPORT */
#if PPPOL2TP_SUPPORT
/**
* Call pppol2tp_create() inside the tcpip_thread context.
*/
static err_t
pppapi_do_pppol2tp_create(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
msg->msg.ppp = pppol2tp_create(msg->msg.msg.l2tpcreate.pppif,
msg->msg.msg.l2tpcreate.netif, msg->msg.msg.l2tpcreate.ipaddr, msg->msg.msg.l2tpcreate.port,
#if PPPOL2TP_AUTH_SUPPORT
msg->msg.msg.l2tpcreate.secret,
msg->msg.msg.l2tpcreate.secret_len,
#else /* PPPOL2TP_AUTH_SUPPORT */
NULL,
#endif /* PPPOL2TP_AUTH_SUPPORT */
msg->msg.msg.l2tpcreate.link_status_cb, msg->msg.msg.l2tpcreate.ctx_cb);
return ERR_OK;
}
/**
* Call pppol2tp_create() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
ppp_pcb*
pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port,
const u8_t *secret, u8_t secret_len,
ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
{
struct pppapi_msg msg;
msg.msg.msg.l2tpcreate.pppif = pppif;
msg.msg.msg.l2tpcreate.netif = netif;
msg.msg.msg.l2tpcreate.ipaddr = ipaddr;
msg.msg.msg.l2tpcreate.port = port;
#if PPPOL2TP_AUTH_SUPPORT
msg.msg.msg.l2tpcreate.secret = secret;
msg.msg.msg.l2tpcreate.secret_len = secret_len;
#endif /* PPPOL2TP_AUTH_SUPPORT */
msg.msg.msg.l2tpcreate.link_status_cb = link_status_cb;
msg.msg.msg.l2tpcreate.ctx_cb = ctx_cb;
tcpip_api_call(pppapi_do_pppol2tp_create, &msg.call);
return msg.msg.ppp;
}
#endif /* PPPOL2TP_SUPPORT */
/**
* Call ppp_connect() inside the tcpip_thread context.
*/
static err_t
pppapi_do_ppp_connect(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
return ppp_connect(msg->msg.ppp, msg->msg.msg.connect.holdoff);
}
/**
* Call ppp_connect() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
err_t
pppapi_connect(ppp_pcb *pcb, u16_t holdoff)
{
struct pppapi_msg msg;
msg.msg.ppp = pcb;
msg.msg.msg.connect.holdoff = holdoff;
return tcpip_api_call(pppapi_do_ppp_connect, &msg.call);
}
#if PPP_SERVER
/**
* Call ppp_listen() inside the tcpip_thread context.
*/
static void
pppapi_do_ppp_listen(struct pppapi_msg_msg *msg)
{
msg->err = ppp_listen(msg->ppp, msg->msg.listen.addrs);
TCPIP_PPPAPI_ACK(msg);
}
/**
* Call ppp_listen() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
err_t
pppapi_listen(ppp_pcb *pcb, struct ppp_addrs *addrs)
{
struct pppapi_msg msg;
msg.function = pppapi_do_ppp_listen;
msg.msg.ppp = pcb;
msg.msg.msg.listen.addrs = addrs;
TCPIP_PPPAPI(&msg);
return msg.msg.err;
}
#endif /* PPP_SERVER */
/**
* Call ppp_close() inside the tcpip_thread context.
*/
static err_t
pppapi_do_ppp_close(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
return ppp_close(msg->msg.ppp, msg->msg.msg.close.nocarrier);
}
/**
* Call ppp_close() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
err_t
pppapi_close(ppp_pcb *pcb, u8_t nocarrier)
{
struct pppapi_msg msg;
msg.msg.ppp = pcb;
msg.msg.msg.close.nocarrier = nocarrier;
return tcpip_api_call(pppapi_do_ppp_close, &msg.call);
}
/**
* Call ppp_free() inside the tcpip_thread context.
*/
static err_t
pppapi_do_ppp_free(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
return ppp_free(msg->msg.ppp);
}
/**
* Call ppp_free() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
err_t
pppapi_free(ppp_pcb *pcb)
{
struct pppapi_msg msg;
msg.msg.ppp = pcb;
return tcpip_api_call(pppapi_do_ppp_free, &msg.call);
}
/**
* Call ppp_ioctl() inside the tcpip_thread context.
*/
static err_t
pppapi_do_ppp_ioctl(struct tcpip_api_call *m)
{
struct pppapi_msg *msg = (struct pppapi_msg *)m;
return ppp_ioctl(msg->msg.ppp, msg->msg.msg.ioctl.cmd, msg->msg.msg.ioctl.arg);
}
/**
* Call ppp_ioctl() in a thread-safe way by running that function inside the
* tcpip_thread context.
*/
err_t
pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg)
{
struct pppapi_msg msg;
msg.msg.ppp = pcb;
msg.msg.msg.ioctl.cmd = cmd;
msg.msg.msg.ioctl.arg = arg;
return tcpip_api_call(pppapi_do_ppp_ioctl, &msg.call);
}
#endif /* LWIP_PPP_API */

File diff suppressed because it is too large Load diff

View file

@ -1,567 +0,0 @@
/**
* @file
* Sequential API Main thread module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
#include "lwip/priv/tcpip_priv.h"
#include "lwip/priv/api_msg.h"
#include "lwip/sys.h"
#include "lwip/memp.h"
#include "lwip/mem.h"
#include "lwip/init.h"
#include "lwip/ip.h"
#include "lwip/pbuf.h"
#include "netif/etharp.h"
#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name)
#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name)
#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name)
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
/* global variables */
static tcpip_init_done_fn tcpip_init_done;
static void *tcpip_init_done_arg;
static sys_mbox_t mbox;
sys_thread_t g_lwip_task = NULL;
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
sys_mutex_t lock_tcpip_core;
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if LWIP_TIMERS
/* wait for a message, timeouts are processed while waiting */
#define TCPIP_MBOX_FETCH(mbox, msg) sys_timeouts_mbox_fetch(mbox, msg)
#else /* LWIP_TIMERS */
/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
#define TCPIP_MBOX_FETCH(mbox, msg) sys_mbox_fetch(mbox, msg)
#endif /* LWIP_TIMERS */
/**
* The main lwIP thread. This thread has exclusive access to lwIP core functions
* (unless access to them is not locked). Other threads communicate with this
* thread using message boxes.
*
* It also starts all the timers to make sure they are running in the right
* thread context.
*
* @param arg unused argument
*/
static void ESP_IRAM_ATTR
tcpip_thread(void *arg)
{
struct tcpip_msg *msg;
LWIP_UNUSED_ARG(arg);
if (tcpip_init_done != NULL) {
tcpip_init_done(tcpip_init_done_arg);
}
LOCK_TCPIP_CORE();
while (1) {
/* MAIN Loop */
UNLOCK_TCPIP_CORE();
LWIP_TCPIP_THREAD_ALIVE();
/* wait for a message, timeouts are processed while waiting */
TCPIP_MBOX_FETCH(&mbox, (void **)&msg);
LOCK_TCPIP_CORE();
if (msg == NULL) {
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
LWIP_ASSERT("tcpip_thread: invalid message", 0);
continue;
}
switch (msg->type) {
#if !LWIP_TCPIP_CORE_LOCKING
case TCPIP_MSG_API:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
msg->msg.api.function(msg->msg.api.msg);
break;
case TCPIP_MSG_API_CALL:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg));
msg->msg.api_call->err = msg->msg.api_call->function(msg->msg.api_call);
#if LWIP_NETCONN_SEM_PER_THREAD
sys_sem_signal(msg->msg.api_call->sem);
#else /* LWIP_NETCONN_SEM_PER_THREAD */
sys_sem_signal(&msg->msg.api_call->sem);
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
break;
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
case TCPIP_MSG_INPKT:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
#if ESP_LWIP
if(msg->msg.inp.p != NULL && msg->msg.inp.netif != NULL) {
#endif
msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif);
#if ESP_LWIP
}
#endif
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
break;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
#if LWIP_TCPIP_TIMEOUT
case TCPIP_MSG_TIMEOUT:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
case TCPIP_MSG_UNTIMEOUT:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
#endif /* LWIP_TCPIP_TIMEOUT */
case TCPIP_MSG_CALLBACK:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
msg->msg.cb.function(msg->msg.cb.ctx);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
case TCPIP_MSG_CALLBACK_STATIC:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
msg->msg.cb.function(msg->msg.cb.ctx);
break;
default:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
LWIP_ASSERT("tcpip_thread: invalid message", 0);
break;
}
}
}
/**
* Pass a received packet to tcpip_thread for input processing
*
* @param p the received packet
* @param inp the network interface on which the packet was received
* @param input_fn input function to call
*/
err_t ESP_IRAM_ATTR
tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
err_t ret;
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));
LOCK_TCPIP_CORE();
ret = input_fn(p, inp);
UNLOCK_TCPIP_CORE();
return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
struct tcpip_msg *msg;
if (!sys_mbox_valid_val(mbox)) {
return ERR_VAL;
}
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_INPKT;
msg->msg.inp.p = p;
msg->msg.inp.netif = inp;
msg->msg.inp.input_fn = input_fn;
#if ESP_PERF
if (p->len > DBG_PERF_FILTER_LEN) {
DBG_PERF_PATH_SET(DBG_PERF_DIR_RX, DBG_PERF_POINT_WIFI_OUT);
}
#endif
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
ESP_STATS_DROP_INC(esp.tcpip_inpkt_post_fail);
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
return ERR_MEM;
}
return ERR_OK;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
}
/**
* Pass a received packet to tcpip_thread for input processing with
* ethernet_input or ip_input
*
* @param p the received packet, p->payload pointing to the Ethernet header or
* to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
* NETIF_FLAG_ETHERNET flags)
* @param inp the network interface on which the packet was received
*/
err_t ESP_IRAM_ATTR
tcpip_input(struct pbuf *p, struct netif *inp)
{
#if LWIP_ETHERNET
if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
return tcpip_inpkt(p, inp, ethernet_input);
} else
#endif /* LWIP_ETHERNET */
return tcpip_inpkt(p, inp, ip_input);
}
/**
* Call a specific function in the thread context of
* tcpip_thread for easy access synchronization.
* A function called in that way may access lwIP core code
* without fearing concurrent access.
*
* @param f the function to call
* @param ctx parameter passed to f
* @param block 1 to block until the request is posted, 0 to non-blocking mode
* @return ERR_OK if the function was called, another err_t if not
*/
err_t
tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
{
struct tcpip_msg *msg;
if (sys_mbox_valid_val(mbox)) {
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_CALLBACK;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
if (block) {
sys_mbox_post(&mbox, msg);
} else {
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
ESP_STATS_DROP_INC(esp.tcpip_cb_post_fail);
memp_free(MEMP_TCPIP_MSG_API, msg);
return ERR_MEM;
}
}
return ERR_OK;
}
return ERR_VAL;
}
#if LWIP_TCPIP_TIMEOUT
/**
* call sys_timeout in tcpip_thread
*
* @param msec time in milliseconds for timeout
* @param h function to be called on timeout
* @param arg argument to pass to timeout function h
* @return ERR_MEM on memory error, ERR_OK otherwise
*/
err_t
tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
{
struct tcpip_msg *msg;
if (sys_mbox_valid_val(mbox)) {
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_TIMEOUT;
msg->msg.tmo.msecs = msecs;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
sys_mbox_post(&mbox, msg);
return ERR_OK;
}
return ERR_VAL;
}
/**
* call sys_untimeout in tcpip_thread
*
* @param msec time in milliseconds for timeout
* @param h function to be called on timeout
* @param arg argument to pass to timeout function h
* @return ERR_MEM on memory error, ERR_OK otherwise
*/
err_t
tcpip_untimeout(sys_timeout_handler h, void *arg)
{
struct tcpip_msg *msg;
if (sys_mbox_valid_val(mbox)) {
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_UNTIMEOUT;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
sys_mbox_post(&mbox, msg);
return ERR_OK;
}
return ERR_VAL;
}
#endif /* LWIP_TCPIP_TIMEOUT */
#if !LWIP_TCPIP_CORE_LOCKING
/**
* Generic way to dispatch an API message in TCPIP thread.
*
* @param fn function to be called from TCPIP thread
* @param apimsg argument to API function
* @param sem semaphore to wait on
* @return ERR_OK if the function was called, another err_t if not
*/
err_t ESP_IRAM_ATTR
tcpip_send_api_msg(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem)
{
LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
if (sys_mbox_valid_val(mbox)) {
TCPIP_MSG_VAR_DECLARE(msg);
TCPIP_MSG_VAR_ALLOC(msg);
TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API;
TCPIP_MSG_VAR_REF(msg).msg.api.function = fn;
TCPIP_MSG_VAR_REF(msg).msg.api.msg = apimsg;
sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg));
sys_arch_sem_wait(sem, 0);
TCPIP_MSG_VAR_FREE(msg);
return ERR_OK;
}
return ERR_VAL;
}
#endif /* !LWIP_TCPIP_CORE_LOCKING */
err_t tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call *call)
{
#if LWIP_TCPIP_CORE_LOCKING
err_t err;
LOCK_TCPIP_CORE();
err = fn(call);
UNLOCK_TCPIP_CORE();
return err;
#else
if (sys_mbox_valid_val(mbox)) {
TCPIP_MSG_VAR_DECLARE(msg);
err_t err;
#if LWIP_NETCONN_SEM_PER_THREAD
call->sem = LWIP_NETCONN_THREAD_SEM_GET();
#else /* LWIP_NETCONN_SEM_PER_THREAD */
err = sys_sem_new(&call->sem, 0);
if (err != ERR_OK) {
return err;
}
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
TCPIP_MSG_VAR_ALLOC(msg);
TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API_CALL;
TCPIP_MSG_VAR_REF(msg).msg.api_call = call;
TCPIP_MSG_VAR_REF(msg).msg.api_call->function = fn;
sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg));
#if LWIP_NETCONN_SEM_PER_THREAD
sys_arch_sem_wait(call->sem, 0);
#else /* LWIP_NETCONN_SEM_PER_THREAD */
sys_arch_sem_wait(&call->sem, 0);
sys_sem_free(&call->sem);
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
TCPIP_MSG_VAR_FREE(msg);
return ERR_OK;
}
return ERR_VAL;
#endif
}
/**
* Allocate a structure for a static callback message and initialize it.
* This is intended to be used to send "static" messages from interrupt context.
*
* @param function the function to call
* @param ctx parameter passed to function
* @return a struct pointer to pass to tcpip_trycallback().
*/
struct tcpip_callback_msg*
tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
{
struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return NULL;
}
msg->type = TCPIP_MSG_CALLBACK_STATIC;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
return (struct tcpip_callback_msg*)msg;
}
/**
* Free a callback message allocated by tcpip_callbackmsg_new().
*
* @param msg the message to free
*/
void
tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg)
{
memp_free(MEMP_TCPIP_MSG_API, msg);
}
/**
* Try to post a callback-message to the tcpip_thread mbox
* This is intended to be used to send "static" messages from interrupt context.
*
* @param msg pointer to the message to post
* @return sys_mbox_trypost() return code
*/
err_t
tcpip_trycallback(struct tcpip_callback_msg* msg)
{
if (!sys_mbox_valid_val(mbox)) {
return ERR_VAL;
}
return sys_mbox_trypost(&mbox, msg);
}
/**
* Initialize this module:
* - initialize all sub modules
* - start the tcpip_thread
*
* @param initfunc a function to call when tcpip_thread is running and finished initializing
* @param arg argument to pass to initfunc
*/
void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{
lwip_init();
tcpip_init_done = initfunc;
tcpip_init_done_arg = arg;
if (sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
}
#if LWIP_TCPIP_CORE_LOCKING
if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
g_lwip_task = sys_thread_new(TCPIP_THREAD_NAME
, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n",
(u32_t)g_lwip_task,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE));
}
/**
* Simple callback function used with tcpip_callback to free a pbuf
* (pbuf_free has a wrong signature for tcpip_callback)
*
* @param p The pbuf (chain) to be dereferenced.
*/
static void
pbuf_free_int(void *p)
{
struct pbuf *q = (struct pbuf *)p;
pbuf_free(q);
}
/**
* A simple wrapper function that allows you to free a pbuf from interrupt context.
*
* @param p The pbuf (chain) to be dereferenced.
* @return ERR_OK if callback could be enqueued, an err_t if not
*/
err_t
pbuf_free_callback(struct pbuf *p)
{
return tcpip_callback_with_block(pbuf_free_int, p, 0);
}
/**
* A simple wrapper function that allows you to free heap memory from
* interrupt context.
*
* @param m the heap memory to free
* @return ERR_OK if callback could be enqueued, an err_t if not
*/
#if ESP_LWIP
static void mem_free_local(void *arg)
{
mem_free(arg);
}
err_t mem_free_callback(void *m)
{
return tcpip_callback_with_block(mem_free_local, m, 0);
#else
err_t mem_free_callback(void *m)
{
#endif
return tcpip_callback_with_block(mem_free, m, 0);
}
#endif /* !NO_SYS */

View file

@ -22,8 +22,8 @@
#include "lwip/ip_addr.h"
#include "tcpip_adapter.h"
#include "apps/dhcpserver.h"
#include "apps/dhcpserver_options.h"
#include "dhcpserver/dhcpserver.h"
#include "dhcpserver/dhcpserver_options.h"
#if ESP_DHCP
@ -524,9 +524,7 @@ static void send_offer(struct dhcps_msg *m, u16_t len)
ip_addr_t ip_temp = IPADDR4_INIT(0x0);
ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
SendOffer_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
#if DHCPS_DEBUG
DHCPS_LOG("dhcps: send_offer>>udp_sendto result %x\n", SendOffer_err_t);
#endif
if (p->ref != 0) {
#if DHCPS_DEBUG
@ -597,9 +595,7 @@ static void send_nak(struct dhcps_msg *m, u16_t len)
ip_addr_t ip_temp = IPADDR4_INIT(0x0);
ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
SendNak_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
#if DHCPS_DEBUG
DHCPS_LOG("dhcps: send_nak>>udp_sendto result %x\n", SendNak_err_t);
#endif
if (p->ref != 0) {
#if DHCPS_DEBUG

View file

@ -13,7 +13,7 @@
// limitations under the License.
#include <string.h>
#include "esp_ping.h"
#include "ping/esp_ping.h"
#include "lwip/ip_addr.h"

View file

@ -42,14 +42,14 @@
#if LWIP_IPV4 && LWIP_RAW /* don't build if not configured for use in lwipopts.h */
#include "ping.h"
#include "ping/ping.h"
#include "lwip/mem.h"
#include "lwip/raw.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/timers.h"
#include "lwip/timeouts.h"
#include "lwip/inet_chksum.h"
#if PING_USE_SOCKETS
@ -58,7 +58,7 @@
#endif /* PING_USE_SOCKETS */
#ifdef ESP_PING
#include "esp_ping.h"
#include "ping/esp_ping.h"
#include "lwip/ip_addr.h"
#endif
/**
@ -155,7 +155,7 @@ ping_send(int s, ip_addr_t *addr)
to.sin_len = sizeof(to);
to.sin_family = AF_INET;
inet_addr_from_ipaddr(&to.sin_addr, ip_2_ip4(addr));
inet_addr_from_ip4addr(&to.sin_addr, ip_2_ip4(addr));
err = sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
@ -182,7 +182,7 @@ ping_recv(int s)
LWIP_DEBUGF( PING_DEBUG, ("ping: invalid sin_family\n"));
} else {
ip4_addr_t fromaddr;
inet_addr_to_ipaddr(&fromaddr, &from.sin_addr);
inet_addr_to_ip4addr(&fromaddr, &from.sin_addr);
iphdr = (struct ip_hdr *)buf;
iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));

View file

@ -1,716 +0,0 @@
/**
* @file
* SNTP client module
*
* This is simple "SNTP" client for the lwIP raw API.
* It is a minimal implementation of SNTPv4 as specified in RFC 4330.
*
* For a list of some public NTP servers, see this link :
* http://support.ntp.org/bin/view/Servers/NTPPoolServers
*
* @todo:
* - set/change servers at runtime
* - complete SNTP_CHECK_RESPONSE checks 3 and 4
* - support broadcast/multicast mode?
*/
/*
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Frédéric Bernon, Simon Goldschmidt
*/
#include "apps/sntp/sntp.h"
#include "lwip/opt.h"
#include "lwip/timers.h"
#include "lwip/udp.h"
#include "lwip/dns.h"
#include "lwip/ip_addr.h"
#include "lwip/pbuf.h"
#include "lwip/dhcp.h"
#include <string.h>
#include <time.h>
#if LWIP_UDP
/* Handle support for more than one server via SNTP_MAX_SERVERS */
#if SNTP_MAX_SERVERS > 1
#define SNTP_SUPPORT_MULTIPLE_SERVERS 1
#else /* NTP_MAX_SERVERS > 1 */
#define SNTP_SUPPORT_MULTIPLE_SERVERS 0
#endif /* NTP_MAX_SERVERS > 1 */
#if (SNTP_UPDATE_DELAY < 15000) && !defined(SNTP_SUPPRESS_DELAY_CHECK)
#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!"
#endif
/* Configure behaviour depending on microsecond or second precision */
#ifdef SNTP_SET_SYSTEM_TIME_US
#define SNTP_CALC_TIME_US 1
#define SNTP_RECEIVE_TIME_SIZE 2
#else
#define SNTP_SET_SYSTEM_TIME_US(sec, us)
#define SNTP_CALC_TIME_US 0
#define SNTP_RECEIVE_TIME_SIZE 1
#endif
/* the various debug levels for this file */
#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE)
#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE)
#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
#define SNTP_ERR_KOD 1
/* SNTP protocol defines */
#define SNTP_MSG_LEN 48
#define SNTP_OFFSET_LI_VN_MODE 0
#define SNTP_LI_MASK 0xC0
#define SNTP_LI_NO_WARNING 0x00
#define SNTP_LI_LAST_MINUTE_61_SEC 0x01
#define SNTP_LI_LAST_MINUTE_59_SEC 0x02
#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */
#define SNTP_VERSION_MASK 0x38
#define SNTP_VERSION (4/* NTP Version 4*/<<3)
#define SNTP_MODE_MASK 0x07
#define SNTP_MODE_CLIENT 0x03
#define SNTP_MODE_SERVER 0x04
#define SNTP_MODE_BROADCAST 0x05
#define SNTP_OFFSET_STRATUM 1
#define SNTP_STRATUM_KOD 0x00
#define SNTP_OFFSET_ORIGINATE_TIME 24
#define SNTP_OFFSET_RECEIVE_TIME 32
#define SNTP_OFFSET_TRANSMIT_TIME 40
/* number of seconds between 1900 and 1970 (MSB=1)*/
#define DIFF_SEC_1900_1970 (2208988800UL)
/* number of seconds between 1970 and Feb 7, 2036 (6:28:16 UTC) (MSB=0) */
#define DIFF_SEC_1970_2036 (2085978496UL)
/**
* SNTP packet format (without optional fields)
* Timestamps are coded as 64 bits:
* - 32 bits seconds since Jan 01, 1970, 00:00
* - 32 bits seconds fraction (0-padded)
* For future use, if the MSB in the seconds part is set, seconds are based
* on Feb 07, 2036, 06:28:16.
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct sntp_msg {
PACK_STRUCT_FLD_8(u8_t li_vn_mode);
PACK_STRUCT_FLD_8(u8_t stratum);
PACK_STRUCT_FLD_8(u8_t poll);
PACK_STRUCT_FLD_8(u8_t precision);
PACK_STRUCT_FIELD(u32_t root_delay);
PACK_STRUCT_FIELD(u32_t root_dispersion);
PACK_STRUCT_FIELD(u32_t reference_identifier);
PACK_STRUCT_FIELD(u32_t reference_timestamp[2]);
PACK_STRUCT_FIELD(u32_t originate_timestamp[2]);
PACK_STRUCT_FIELD(u32_t receive_timestamp[2]);
PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/* function prototypes */
static void sntp_request(void *arg);
/** The operating mode */
static u8_t sntp_opmode;
/** The UDP pcb used by the SNTP client */
static struct udp_pcb* sntp_pcb;
/** Names/Addresses of servers */
struct sntp_server {
#if SNTP_SERVER_DNS
char* name;
#endif /* SNTP_SERVER_DNS */
ip_addr_t addr;
};
static struct sntp_server sntp_servers[SNTP_MAX_SERVERS];
#if SNTP_GET_SERVERS_FROM_DHCP
static u8_t sntp_set_servers_from_dhcp;
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#if SNTP_SUPPORT_MULTIPLE_SERVERS
/** The currently used server (initialized to 0) */
static u8_t sntp_current_server;
#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
#define sntp_current_server 0
#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
#if SNTP_RETRY_TIMEOUT_EXP
#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT
/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */
static u32_t sntp_retry_timeout;
#else /* SNTP_RETRY_TIMEOUT_EXP */
#define SNTP_RESET_RETRY_TIMEOUT()
#define sntp_retry_timeout SNTP_RETRY_TIMEOUT
#endif /* SNTP_RETRY_TIMEOUT_EXP */
#if SNTP_CHECK_RESPONSE >= 1
/** Saves the last server address to compare with response */
static ip_addr_t sntp_last_server_address;
#endif /* SNTP_CHECK_RESPONSE >= 1 */
#if SNTP_CHECK_RESPONSE >= 2
/** Saves the last timestamp sent (which is sent back by the server)
* to compare against in response */
static u32_t sntp_last_timestamp_sent[2];
#endif /* SNTP_CHECK_RESPONSE >= 2 */
/**
* SNTP processing of received timestamp
*/
static void
sntp_process(u32_t *receive_timestamp)
{
/* convert SNTP time (1900-based) to unix GMT time (1970-based)
* if MSB is 0, SNTP time is 2036-based!
*/
u32_t rx_secs = ntohl(receive_timestamp[0]);
int is_1900_based = ((rx_secs & 0x80000000) != 0);
u32_t t = is_1900_based ? (rx_secs - DIFF_SEC_1900_1970) : (rx_secs + DIFF_SEC_1970_2036);
time_t tim = t;
#if SNTP_CALC_TIME_US
u32_t us = ntohl(receive_timestamp[1]) / 4295;
SNTP_SET_SYSTEM_TIME_US(t, us);
/* display local time from GMT time */
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&tim), us));
#else /* SNTP_CALC_TIME_US */
/* change system time and/or the update the RTC clock */
SNTP_SET_SYSTEM_TIME(t);
/* display local time from GMT time */
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&tim)));
#endif /* SNTP_CALC_TIME_US */
LWIP_UNUSED_ARG(tim);
}
/**
* Initialize request struct to be sent to server.
*/
static void
sntp_initialize_request(struct sntp_msg *req)
{
memset(req, 0, SNTP_MSG_LEN);
req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
#if SNTP_CHECK_RESPONSE >= 2
{
u32_t sntp_time_sec, sntp_time_us;
/* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us);
sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970);
req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];
/* we send/save us instead of fraction to be faster... */
sntp_last_timestamp_sent[1] = htonl(sntp_time_us);
req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
}
#endif /* SNTP_CHECK_RESPONSE >= 2 */
}
/**
* Retry: send a new request (and increase retry timeout).
*
* @param arg is unused (only necessary to conform to sys_timeout)
*/
static void
sntp_retry(void* arg)
{
LWIP_UNUSED_ARG(arg);
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n",
sntp_retry_timeout));
/* set up a timer to send a retry and increase the retry delay */
sys_timeout(sntp_retry_timeout, sntp_request, NULL);
#if SNTP_RETRY_TIMEOUT_EXP
{
u32_t new_retry_timeout;
/* increase the timeout for next retry */
new_retry_timeout = sntp_retry_timeout << 1;
/* limit to maximum timeout and prevent overflow */
if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
(new_retry_timeout > sntp_retry_timeout)) {
sntp_retry_timeout = new_retry_timeout;
}
}
#endif /* SNTP_RETRY_TIMEOUT_EXP */
}
#if SNTP_SUPPORT_MULTIPLE_SERVERS
/**
* If Kiss-of-Death is received (or another packet parsing error),
* try the next server or retry the current server and increase the retry
* timeout if only one server is available.
* (implicitly, SNTP_MAX_SERVERS > 1)
*
* @param arg is unused (only necessary to conform to sys_timeout)
*/
static void
sntp_try_next_server(void* arg)
{
u8_t old_server, i;
LWIP_UNUSED_ARG(arg);
old_server = sntp_current_server;
for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) {
sntp_current_server++;
if (sntp_current_server >= SNTP_MAX_SERVERS) {
sntp_current_server = 0;
}
if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr)
#if SNTP_SERVER_DNS
|| (sntp_servers[sntp_current_server].name != NULL)
#endif
) {
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n",
(u16_t)sntp_current_server));
/* new server: reset retry timeout */
SNTP_RESET_RETRY_TIMEOUT();
/* instantly send a request to the next server */
sntp_request(NULL);
return;
}
}
/* no other valid server found */
sntp_current_server = old_server;
sntp_retry(NULL);
}
#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
/* Always retry on error if only one server is supported */
#define sntp_try_next_server sntp_retry
#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
/** UDP recv callback for the sntp pcb */
static void
sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
u8_t mode;
u8_t stratum;
u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
err_t err;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
/* packet received: stop retry timeout */
sys_untimeout(sntp_try_next_server, NULL);
sys_untimeout(sntp_request, NULL);
err = ERR_ARG;
#if SNTP_CHECK_RESPONSE >= 1
/* check server address and port */
if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) &&
(port == SNTP_PORT))
#else /* SNTP_CHECK_RESPONSE >= 1 */
LWIP_UNUSED_ARG(addr);
LWIP_UNUSED_ARG(port);
#endif /* SNTP_CHECK_RESPONSE >= 1 */
{
/* process the response */
if (p->tot_len == SNTP_MSG_LEN) {
pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE);
mode &= SNTP_MODE_MASK;
/* if this is a SNTP response... */
if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) ||
((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) {
pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM);
if (stratum == SNTP_STRATUM_KOD) {
/* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
err = SNTP_ERR_KOD;
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
} else {
#if SNTP_CHECK_RESPONSE >= 2
/* check originate_timetamp against sntp_last_timestamp_sent */
u32_t originate_timestamp[2];
pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME);
if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
(originate_timestamp[1] != sntp_last_timestamp_sent[1]))
{
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n"));
} else
#endif /* SNTP_CHECK_RESPONSE >= 2 */
/* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
{
/* correct answer */
err = ERR_OK;
pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_TRANSMIT_TIME);
}
}
} else {
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
/* wait for correct response */
err = ERR_TIMEOUT;
}
} else {
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
}
}
#if SNTP_CHECK_RESPONSE >= 1
else {
/* packet from wrong remote address or port, wait for correct response */
err = ERR_TIMEOUT;
}
#endif /* SNTP_CHECK_RESPONSE >= 1 */
pbuf_free(p);
if (err == ERR_OK) {
sntp_process(receive_timestamp);
/* Set up timeout for next request (only if poll response was received)*/
if (sntp_opmode == SNTP_OPMODE_POLL) {
/* Correct response, reset retry timeout */
SNTP_RESET_RETRY_TIMEOUT();
sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL);
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n",
(u32_t)SNTP_UPDATE_DELAY));
}
} else if (err != ERR_TIMEOUT) {
/* Errors are only processed in case of an explicit poll response */
if (sntp_opmode == SNTP_OPMODE_POLL) {
if (err == SNTP_ERR_KOD) {
/* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
sntp_try_next_server(NULL);
} else {
/* another error, try the same server again */
sntp_retry(NULL);
}
}
}
}
/** Actually send an sntp request to a server.
*
* @param server_addr resolved IP address of the SNTP server
*/
static void
sntp_send_request(const ip_addr_t *server_addr)
{
struct pbuf* p;
p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM);
if (p != NULL) {
struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload;
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n"));
/* initialize request message */
sntp_initialize_request(sntpmsg);
/* send request */
udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT);
/* free the pbuf after sending it */
pbuf_free(p);
/* set up receive timeout: try next server or retry on timeout */
sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
#if SNTP_CHECK_RESPONSE >= 1
/* save server address to verify it in sntp_recv */
ip_addr_set(&sntp_last_server_address, server_addr);
#endif /* SNTP_CHECK_RESPONSE >= 1 */
} else {
LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
(u32_t)SNTP_RETRY_TIMEOUT));
/* out of memory: set up a timer to send a retry */
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
}
}
#if SNTP_SERVER_DNS
/**
* DNS found callback when using DNS names as server address.
*/
static void
sntp_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg)
{
LWIP_UNUSED_ARG(hostname);
LWIP_UNUSED_ARG(arg);
if (ipaddr != NULL) {
/* Address resolved, send request */
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n"));
sntp_send_request(ipaddr);
} else {
/* DNS resolving failed -> try another server */
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
sntp_try_next_server(NULL);
}
}
#endif /* SNTP_SERVER_DNS */
/**
* Send out an sntp request.
*
* @param arg is unused (only necessary to conform to sys_timeout)
*/
static void
sntp_request(void *arg)
{
ip_addr_t sntp_server_address;
err_t err;
LWIP_UNUSED_ARG(arg);
/* initialize SNTP server address */
#if SNTP_SERVER_DNS
if (sntp_servers[sntp_current_server].name) {
/* always resolve the name and rely on dns-internal caching & timeout */
ip_addr_set_zero(&sntp_servers[sntp_current_server].addr);
err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address,
sntp_dns_found, NULL);
if (err == ERR_INPROGRESS) {
/* DNS request sent, wait for sntp_dns_found being called */
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n"));
return;
} else if (err == ERR_OK) {
sntp_servers[sntp_current_server].addr = sntp_server_address;
}
} else
#endif /* SNTP_SERVER_DNS */
{
sntp_server_address = sntp_servers[sntp_current_server].addr;
err = (ip_addr_isany_val(sntp_server_address)) ? ERR_ARG : ERR_OK;
}
if (err == ERR_OK) {
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %s\n",
ipaddr_ntoa(&sntp_server_address)));
sntp_send_request(&sntp_server_address);
} else {
/* address conversion failed, try another server */
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
}
}
/**
* Initialize this module.
* Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC).
*/
void
sntp_init(void)
{
#ifdef SNTP_SERVER_ADDRESS
#if SNTP_SERVER_DNS
sntp_setservername(0, SNTP_SERVER_ADDRESS);
#else
#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0
#endif
#endif /* SNTP_SERVER_ADDRESS */
if (sntp_pcb == NULL) {
sntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL);
if (sntp_pcb != NULL) {
udp_recv(sntp_pcb, sntp_recv, NULL);
if (sntp_opmode == SNTP_OPMODE_POLL) {
SNTP_RESET_RETRY_TIMEOUT();
#if SNTP_STARTUP_DELAY
sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL);
#else
sntp_request(NULL);
#endif
} else if (sntp_opmode == SNTP_OPMODE_LISTENONLY) {
ip_set_option(sntp_pcb, SOF_BROADCAST);
udp_bind(sntp_pcb, IP_ANY_TYPE, SNTP_PORT);
}
}
}
}
/**
* Stop this module.
*/
void
sntp_stop(void)
{
if (sntp_pcb != NULL) {
sys_untimeout(sntp_request, NULL);
udp_remove(sntp_pcb);
sntp_pcb = NULL;
}
}
/**
* Get enabled state.
*/
u8_t sntp_enabled(void)
{
return (sntp_pcb != NULL)? 1 : 0;
}
/**
* Sets the operating mode.
* @param operating_mode one of the available operating modes
*/
void
sntp_setoperatingmode(u8_t operating_mode)
{
LWIP_ASSERT("Invalid operating mode", operating_mode <= SNTP_OPMODE_LISTENONLY);
LWIP_ASSERT("Operating mode must not be set while SNTP client is running", sntp_pcb == NULL);
sntp_opmode = operating_mode;
}
/**
* Gets the operating mode.
*/
u8_t
sntp_getoperatingmode(void)
{
return sntp_opmode;
}
#if SNTP_GET_SERVERS_FROM_DHCP
/**
* Config SNTP server handling by IP address, name, or DHCP; clear table
* @param set_servers_from_dhcp enable or disable getting server addresses from dhcp
*/
void
sntp_servermode_dhcp(int set_servers_from_dhcp)
{
u8_t new_mode = set_servers_from_dhcp ? 1 : 0;
if (sntp_set_servers_from_dhcp != new_mode) {
sntp_set_servers_from_dhcp = new_mode;
}
}
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
/**
* Initialize one of the NTP servers by IP address
*
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param dnsserver IP address of the NTP server to set
*/
void
sntp_setserver(u8_t idx, const ip_addr_t *server)
{
if (idx < SNTP_MAX_SERVERS) {
if (server != NULL) {
sntp_servers[idx].addr = (*server);
} else {
ip_addr_set_zero(&sntp_servers[idx].addr);
}
#if SNTP_SERVER_DNS
sntp_servers[idx].name = NULL;
#endif
}
}
#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP
/**
* Initialize one of the NTP servers by IP address, required by DHCP
*
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param dnsserver IP address of the NTP server to set
*/
void
dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
{
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
(sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num));
if (sntp_set_servers_from_dhcp && num) {
u8_t i;
for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) {
ip_addr_t addr;
ip_addr_copy_from_ip4(addr, server[i]);
sntp_setserver(i, &addr);
}
for (i = num; i < SNTP_MAX_SERVERS; i++) {
sntp_setserver(i, NULL);
}
}
}
#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */
/**
* Obtain one of the currently configured by IP address (or DHCP) NTP servers
*
* @param numdns the index of the NTP server
* @return IP address of the indexed NTP server or "ip_addr_any" if the NTP
* server has not been configured by address (or at all).
*/
ip_addr_t
sntp_getserver(u8_t idx)
{
if (idx < SNTP_MAX_SERVERS) {
return sntp_servers[idx].addr;
}
return *IP_ADDR_ANY;
}
#if SNTP_SERVER_DNS
/**
* Initialize one of the NTP servers by name
*
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param dnsserver DNS name of the NTP server to set, to be resolved at contact time
*/
void
sntp_setservername(u8_t idx, char *server)
{
if (idx < SNTP_MAX_SERVERS) {
sntp_servers[idx].name = server;
}
}
/**
* Obtain one of the currently configured by name NTP servers.
*
* @param numdns the index of the NTP server
* @return IP address of the indexed NTP server or NULL if the NTP
* server has not been configured by name (or at all)
*/
char *
sntp_getservername(u8_t idx)
{
if (idx < SNTP_MAX_SERVERS) {
return sntp_servers[idx].name;
}
return NULL;
}
#endif /* SNTP_SERVER_DNS */
#endif /* LWIP_UDP */

View file

@ -1,25 +1,28 @@
#
# Component Makefile
#
COMPONENT_SUBMODULES += lwip
COMPONENT_ADD_INCLUDEDIRS := \
include/lwip \
include/lwip/port \
include/lwip/posix \
apps/ping
ifdef CONFIG_PPP_SUPPORT
LWIP_PPP_DIRS := netif/ppp/polarssl netif/ppp
else
LWIP_PPP_DIRS :=
endif
include/apps \
lwip/src/include \
port/esp32/include \
port/esp32/include/arch
COMPONENT_SRCDIRS := \
api \
apps apps/sntp apps/ping \
core core/ipv4 core/ipv6 \
$(LWIP_PPP_DIRS) netif \
port/freertos port/netif port/debug port
apps/dhcpserver \
apps/ping \
lwip/src/api \
lwip/src/apps/sntp \
lwip/src/core \
lwip/src/core/ipv4 \
lwip/src/core/ipv6 \
lwip/src/netif \
lwip/src/netif/ppp \
port/esp32 \
port/esp32/freertos \
port/esp32/netif \
port/esp32/debug
CFLAGS += -Wno-address # lots of LWIP source files evaluate macros that check address of stack variables

View file

@ -1,108 +0,0 @@
/**
* @file
* Common functions used throughout the stack.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt
*
*/
#include "lwip/opt.h"
#include "lwip/def.h"
/**
* These are reference implementations of the byte swapping functions.
* Again with the aim of being simple, correct and fully portable.
* Byte swapping is the second thing you would want to optimize. You will
* need to port it to your architecture and in your cc.h:
*
* #define LWIP_PLATFORM_BYTESWAP 1
* #define LWIP_PLATFORM_HTONS(x) <your_htons>
* #define LWIP_PLATFORM_HTONL(x) <your_htonl>
*
* Note ntohs() and ntohl() are merely references to the htonx counterparts.
*/
#if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN)
/**
* Convert an u16_t from host- to network byte order.
*
* @param n u16_t in host byte order
* @return n in network byte order
*/
u16_t
lwip_htons(u16_t n)
{
return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
}
/**
* Convert an u16_t from network- to host byte order.
*
* @param n u16_t in network byte order
* @return n in host byte order
*/
u16_t
lwip_ntohs(u16_t n)
{
return lwip_htons(n);
}
/**
* Convert an u32_t from host- to network byte order.
*
* @param n u32_t in host byte order
* @return n in network byte order
*/
u32_t
lwip_htonl(u32_t n)
{
return ((n & 0xff) << 24) |
((n & 0xff00) << 8) |
((n & 0xff0000UL) >> 8) |
((n & 0xff000000UL) >> 24);
}
/**
* Convert an u32_t from network- to host byte order.
*
* @param n u32_t in network byte order
* @return n in host byte order
*/
u32_t
lwip_ntohl(u32_t n)
{
return lwip_htonl(n);
}
#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */

File diff suppressed because it is too large Load diff

View file

@ -1,612 +0,0 @@
/**
* @file
* Incluse internet checksum functions.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/inet_chksum.h"
#include "lwip/def.h"
#include "lwip/ip_addr.h"
#include <stddef.h>
#include <string.h>
/* These are some reference implementations of the checksum algorithm, with the
* aim of being simple, correct and fully portable. Checksumming is the
* first thing you would want to optimize for your platform. If you create
* your own version, link it in and in your cc.h put:
*
* #define LWIP_CHKSUM <your_checksum_routine>
*
* Or you can select from the implementations below by defining
* LWIP_CHKSUM_ALGORITHM to 1, 2 or 3.
*/
#ifndef LWIP_CHKSUM
# define LWIP_CHKSUM lwip_standard_chksum
# ifndef LWIP_CHKSUM_ALGORITHM
# define LWIP_CHKSUM_ALGORITHM 2
# endif
u16_t lwip_standard_chksum(const void *dataptr, int len);
#endif
/* If none set: */
#ifndef LWIP_CHKSUM_ALGORITHM
# define LWIP_CHKSUM_ALGORITHM 0
#endif
#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
/**
* lwip checksum
*
* @param dataptr points to start of data to be summed at any boundary
* @param len length of data to be summed
* @return host order (!) lwip checksum (non-inverted Internet sum)
*
* @note accumulator size limits summable length to 64k
* @note host endianess is irrelevant (p3 RFC1071)
*/
u16_t
lwip_standard_chksum(const void *dataptr, int len)
{
u32_t acc;
u16_t src;
const u8_t *octetptr;
acc = 0;
/* dataptr may be at odd or even addresses */
octetptr = (const u8_t*)dataptr;
while (len > 1) {
/* declare first octet as most significant
thus assume network order, ignoring host order */
src = (*octetptr) << 8;
octetptr++;
/* declare second octet as least significant */
src |= (*octetptr);
octetptr++;
acc += src;
len -= 2;
}
if (len > 0) {
/* accumulate remaining octet */
src = (*octetptr) << 8;
acc += src;
}
/* add deferred carry bits */
acc = (acc >> 16) + (acc & 0x0000ffffUL);
if ((acc & 0xffff0000UL) != 0) {
acc = (acc >> 16) + (acc & 0x0000ffffUL);
}
/* This maybe a little confusing: reorder sum using htons()
instead of ntohs() since it has a little less call overhead.
The caller must invert bits for Internet sum ! */
return htons((u16_t)acc);
}
#endif
#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */
/*
* Curt McDowell
* Broadcom Corp.
* csm@broadcom.com
*
* IP checksum two bytes at a time with support for
* unaligned buffer.
* Works for len up to and including 0x20000.
* by Curt McDowell, Broadcom Corp. 12/08/2005
*
* @param dataptr points to start of data to be summed at any boundary
* @param len length of data to be summed
* @return host order (!) lwip checksum (non-inverted Internet sum)
*/
u16_t
lwip_standard_chksum(const void *dataptr, int len)
{
const u8_t *pb = (const u8_t *)dataptr;
const u16_t *ps;
u16_t t = 0;
u32_t sum = 0;
int odd = ((mem_ptr_t)pb & 1);
/* Get aligned to u16_t */
if (odd && len > 0) {
((u8_t *)&t)[1] = *pb++;
len--;
}
/* Add the bulk of the data */
ps = (const u16_t *)(const void *)pb;
while (len > 1) {
sum += *ps++;
len -= 2;
}
/* Consume left-over byte, if any */
if (len > 0) {
((u8_t *)&t)[0] = *(const u8_t *)ps;
}
/* Add end bytes */
sum += t;
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
sum = FOLD_U32T(sum);
sum = FOLD_U32T(sum);
/* Swap if alignment was odd */
if (odd) {
sum = SWAP_BYTES_IN_WORD(sum);
}
return (u16_t)sum;
}
#endif
#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */
/**
* An optimized checksum routine. Basically, it uses loop-unrolling on
* the checksum loop, treating the head and tail bytes specially, whereas
* the inner loop acts on 8 bytes at a time.
*
* @arg start of buffer to be checksummed. May be an odd byte address.
* @len number of bytes in the buffer to be checksummed.
* @return host order (!) lwip checksum (non-inverted Internet sum)
*
* by Curt McDowell, Broadcom Corp. December 8th, 2005
*/
u16_t
lwip_standard_chksum(const void *dataptr, int len)
{
const u8_t *pb = (const u8_t *)dataptr;
const u16_t *ps;
u16_t t = 0;
const u32_t *pl;
u32_t sum = 0, tmp;
/* starts at odd byte address? */
int odd = ((mem_ptr_t)pb & 1);
if (odd && len > 0) {
((u8_t *)&t)[1] = *pb++;
len--;
}
ps = (const u16_t *)(const void*)pb;
if (((mem_ptr_t)ps & 3) && len > 1) {
sum += *ps++;
len -= 2;
}
pl = (const u32_t *)(const void*)ps;
while (len > 7) {
tmp = sum + *pl++; /* ping */
if (tmp < sum) {
tmp++; /* add back carry */
}
sum = tmp + *pl++; /* pong */
if (sum < tmp) {
sum++; /* add back carry */
}
len -= 8;
}
/* make room in upper bits */
sum = FOLD_U32T(sum);
ps = (const u16_t *)pl;
/* 16-bit aligned word remaining? */
while (len > 1) {
sum += *ps++;
len -= 2;
}
/* dangling tail byte remaining? */
if (len > 0) { /* include odd byte */
((u8_t *)&t)[0] = *(const u8_t *)ps;
}
sum += t; /* add end bytes */
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
sum = FOLD_U32T(sum);
sum = FOLD_U32T(sum);
if (odd) {
sum = SWAP_BYTES_IN_WORD(sum);
}
return (u16_t)sum;
}
#endif
/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
static u16_t ESP_IRAM_ATTR
inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
{
struct pbuf *q;
u8_t swapped = 0;
/* iterate through all pbuf in chain */
for (q = p; q != NULL; q = q->next) {
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
(void *)q, (void *)q->next));
acc += LWIP_CHKSUM(q->payload, q->len);
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
/* just executing this next line is probably faster that the if statement needed
to check whether we really need to execute it, and does no harm */
acc = FOLD_U32T(acc);
if (q->len % 2 != 0) {
swapped = 1 - swapped;
acc = SWAP_BYTES_IN_WORD(acc);
}
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
}
if (swapped) {
acc = SWAP_BYTES_IN_WORD(acc);
}
acc += (u32_t)htons((u16_t)proto);
acc += (u32_t)htons(proto_len);
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
return (u16_t)~(acc & 0xffffUL);
}
#if LWIP_IPV4
/* inet_chksum_pseudo:
*
* Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
* IP addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t ESP_IRAM_ATTR
inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip4_addr_t *src, const ip4_addr_t *dest)
{
u32_t acc;
u32_t addr;
addr = ip4_addr_get_u32(src);
acc = (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
addr = ip4_addr_get_u32(dest);
acc += (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_base(p, proto, proto_len, acc);
}
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
/**
* Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain.
* IPv6 addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ipv6 address (used for checksum of pseudo header)
* @param dst destination ipv6 address (used for checksum of pseudo header)
* @param proto ipv6 protocol/next header (used for checksum of pseudo header)
* @param proto_len length of the ipv6 payload (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip6_addr_t *src, const ip6_addr_t *dest)
{
u32_t acc = 0;
u32_t addr;
u8_t addr_part;
for (addr_part = 0; addr_part < 4; addr_part++) {
addr = src->addr[addr_part];
acc += (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
addr = dest->addr[addr_part];
acc += (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
}
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_base(p, proto, proto_len, acc);
}
#endif /* LWIP_IPV6 */
/* ip_chksum_pseudo:
*
* Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
* IP addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t ESP_IRAM_ATTR
ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip_addr_t *src, const ip_addr_t *dest)
{
#if LWIP_IPV6
if (IP_IS_V6(dest)) {
return ip6_chksum_pseudo(p, proto, proto_len, ip_2_ip6(src), ip_2_ip6(dest));
}
#endif /* LWIP_IPV6 */
#if LWIP_IPV4 && LWIP_IPV6
else
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#if LWIP_IPV4
{
return inet_chksum_pseudo(p, proto, proto_len, ip_2_ip4(src), ip_2_ip4(dest));
}
#endif /* LWIP_IPV4 */
}
/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
static u16_t
inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, u32_t acc)
{
struct pbuf *q;
u8_t swapped = 0;
u16_t chklen;
/* iterate through all pbuf in chain */
for (q = p; (q != NULL) && (chksum_len > 0); q = q->next) {
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
(void *)q, (void *)q->next));
chklen = q->len;
if (chklen > chksum_len) {
chklen = chksum_len;
}
acc += LWIP_CHKSUM(q->payload, chklen);
chksum_len -= chklen;
LWIP_ASSERT("delete me", chksum_len < 0x7fff);
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
/* fold the upper bit down */
acc = FOLD_U32T(acc);
if (q->len % 2 != 0) {
swapped = 1 - swapped;
acc = SWAP_BYTES_IN_WORD(acc);
}
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
}
if (swapped) {
acc = SWAP_BYTES_IN_WORD(acc);
}
acc += (u32_t)htons((u16_t)proto);
acc += (u32_t)htons(proto_len);
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
return (u16_t)~(acc & 0xffffUL);
}
#if LWIP_IPV4
/* inet_chksum_pseudo_partial:
*
* Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
* IP addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest)
{
u32_t acc;
u32_t addr;
addr = ip4_addr_get_u32(src);
acc = (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
addr = ip4_addr_get_u32(dest);
acc += (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc);
}
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
/**
* Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain.
* IPv6 addresses are expected to be in network byte order. Will only compute for a
* portion of the payload.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ipv6 address (used for checksum of pseudo header)
* @param dst destination ipv6 address (used for checksum of pseudo header)
* @param proto ipv6 protocol/next header (used for checksum of pseudo header)
* @param proto_len length of the ipv6 payload (used for checksum of pseudo header)
* @param chksum_len number of payload bytes used to compute chksum
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest)
{
u32_t acc = 0;
u32_t addr;
u8_t addr_part;
for (addr_part = 0; addr_part < 4; addr_part++) {
addr = src->addr[addr_part];
acc += (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
addr = dest->addr[addr_part];
acc += (addr & 0xffffUL);
acc += ((addr >> 16) & 0xffffUL);
}
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc);
}
#endif /* LWIP_IPV6 */
/* ip_chksum_pseudo_partial:
*
* Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest)
{
#if LWIP_IPV6
if (IP_IS_V6(dest)) {
return ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip6(src), ip_2_ip6(dest));
}
#endif /* LWIP_IPV6 */
#if LWIP_IPV4 && LWIP_IPV6
else
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#if LWIP_IPV4
{
return inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip4(src), ip_2_ip4(dest));
}
#endif /* LWIP_IPV4 */
}
/* inet_chksum:
*
* Calculates the Internet checksum over a portion of memory. Used primarily for IP
* and ICMP.
*
* @param dataptr start of the buffer to calculate the checksum (no alignment needed)
* @param len length of the buffer to calculate the checksum
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
inet_chksum(const void *dataptr, u16_t len)
{
return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len);
}
/**
* Calculate a checksum over a chain of pbufs (without pseudo-header, much like
* inet_chksum only pbufs are used).
*
* @param p pbuf chain over that the checksum should be calculated
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
inet_chksum_pbuf(struct pbuf *p)
{
u32_t acc;
struct pbuf *q;
u8_t swapped;
acc = 0;
swapped = 0;
for (q = p; q != NULL; q = q->next) {
acc += LWIP_CHKSUM(q->payload, q->len);
acc = FOLD_U32T(acc);
if (q->len % 2 != 0) {
swapped = 1 - swapped;
acc = SWAP_BYTES_IN_WORD(acc);
}
}
if (swapped) {
acc = SWAP_BYTES_IN_WORD(acc);
}
return (u16_t)~(acc & 0xffffUL);
}
/* These are some implementations for LWIP_CHKSUM_COPY, which copies data
* like MEMCPY but generates a checksum at the same time. Since this is a
* performance-sensitive function, you might want to create your own version
* in assembly targeted at your hardware by defining it in lwipopts.h:
* #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len)
*/
#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */
/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM.
* For architectures with big caches, data might still be in cache when
* generating the checksum after copying.
*/
u16_t
lwip_chksum_copy(void *dst, const void *src, u16_t len)
{
MEMCPY(dst, src, len);
return LWIP_CHKSUM(dst, len);
}
#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */

View file

@ -1,376 +0,0 @@
/**
* @file
* Modules initialization
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/init.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#include "lwip/sockets.h"
#include "lwip/ip.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/autoip.h"
#include "lwip/igmp.h"
#include "lwip/dns.h"
#include "lwip/timers.h"
#include "netif/etharp.h"
#include "lwip/ip6.h"
#include "lwip/nd6.h"
#include "lwip/mld6.h"
#include "lwip/api.h"
#include "netif/ppp/ppp_impl.h"
#if ! ESP_PERF
/* Compile-time sanity checks for configuration errors.
* These can be done independently of LWIP_DEBUG, without penalty.
*/
#ifndef BYTE_ORDER
#error "BYTE_ORDER is not defined, you have to define it in your cc.h"
#endif
#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV)
#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_UDPLITE)
#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_DHCP)
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_MULTICAST_TX_OPTIONS)
#error "If you want to use IGMP/LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_DNS)
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */
#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0))
#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h"
#endif
#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0))
#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0))
#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
#endif
#if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS)
#error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h"
#endif
#if (LWIP_IGMP && !LWIP_IPV4)
#error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h"
#endif
#if (LWIP_MULTICAST_TX_OPTIONS && !LWIP_IPV4)
#error "LWIP_MULTICAST_TX_OPTIONS needs LWIP_IPV4 enabled in your lwipopts.h"
#endif
#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0))
#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
#endif
/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)))
#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
#endif
#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!"
#endif
#endif /* !MEMP_MEM_MALLOC */
#if LWIP_WND_SCALE
//#if (LWIP_TCP && (TCP_WND > 0xffffffff))
//#error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h"
//#endif
#if (LWIP_TCP && LWIP_WND_SCALE && (TCP_RCV_SCALE > 14))
#error "The maximum valid window scale value is 14!"
#endif
//#if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE)))
//#error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!"
//#endif
//#if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0))
//#error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!"
//#endif
#else /* LWIP_WND_SCALE */
#if ! ESP_PER_SOC_TCP_WND
#if (LWIP_TCP && (TCP_WND > 0xffff))
#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)"
#endif
#endif
#endif /* LWIP_WND_SCALE */
#if ! ESP_PER_SOC_TCP_WND
#if (LWIP_TCP && (TCP_SND_QUEUELEN(0) > 0xffff))
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
#endif
#if (LWIP_TCP && (TCP_SND_QUEUELEN(0) < 2))
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
#endif
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
#endif
#endif
#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)))
#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
#endif
#if (LWIP_NETIF_API && (NO_SYS==1))
#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if (LWIP_PPP_API && (NO_SYS==1))
#error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if (LWIP_PPP_API && (PPP_SUPPORT==0))
#error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h"
#endif
#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP)
#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h"
#endif
#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK)
#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h"
#endif
#if (!LWIP_ARP && LWIP_AUTOIP)
#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h"
#endif
#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API)))
#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h"
#endif
#if (MEM_LIBC_MALLOC && MEM_USE_POOLS)
#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h"
#endif
#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS)
#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
#endif
#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT)
#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf"
#endif
#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
#endif
#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT && !PPPOL2TP_SUPPORT
#error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on"
#endif
#if PPP_SUPPORT && !PPP_IPV4_SUPPORT && !PPP_IPV6_SUPPORT
#error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on"
#endif
#if PPP_SUPPORT && PPP_IPV4_SUPPORT && !LWIP_IPV4
#error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on"
#endif
#if PPP_SUPPORT && PPP_IPV6_SUPPORT && !LWIP_IPV6
#error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on"
#endif
#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT)
#error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT"
#endif
#if (LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND)
#error "When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value"
#endif
#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING
#error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too"
#endif
#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE
#error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets"
#endif
#if IP_FRAG && IP_FRAG_USES_STATIC_BUF && LWIP_NETIF_TX_SINGLE_PBUF
#error "LWIP_NETIF_TX_SINGLE_PBUF does not work with IP_FRAG_USES_STATIC_BUF==1 as that creates pbuf queues"
#endif
#if LWIP_NETCONN && LWIP_TCP
#if NETCONN_COPY != TCP_WRITE_FLAG_COPY
#error "NETCONN_COPY != TCP_WRITE_FLAG_COPY"
#endif
#if NETCONN_MORE != TCP_WRITE_FLAG_MORE
#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
#endif
#endif /* LWIP_NETCONN && LWIP_TCP */
#if LWIP_SOCKET
/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */
#if SO_REUSEADDR != SOF_REUSEADDR
#error "WARNING: SO_REUSEADDR != SOF_REUSEADDR"
#endif
#if SO_KEEPALIVE != SOF_KEEPALIVE
#error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE"
#endif
#if SO_BROADCAST != SOF_BROADCAST
#error "WARNING: SO_BROADCAST != SOF_BROADCAST"
#endif
#endif /* LWIP_SOCKET */
/* Compile-time checks for deprecated options.
*/
#ifdef MEMP_NUM_TCPIP_MSG
#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef TCP_REXMIT_DEBUG
#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef RAW_STATS
#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef ETHARP_QUEUE_FIRST
#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef ETHARP_ALWAYS_INSERT
#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h."
#endif
#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS
#define LWIP_DISABLE_TCP_SANITY_CHECKS 0
#endif
#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS
#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0
#endif
/* MEMP sanity checks */
#if !LWIP_DISABLE_MEMP_SANITY_CHECKS
#if LWIP_NETCONN
#if MEMP_MEM_MALLOC
#if !MEMP_NUM_NETCONN && LWIP_SOCKET
#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!"
#endif
#else /* MEMP_MEM_MALLOC */
#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB)
#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error."
#endif
#endif /* MEMP_MEM_MALLOC */
#endif /* LWIP_NETCONN */
#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */
/* TCP sanity checks */
#if !LWIP_DISABLE_TCP_SANITY_CHECKS
#if ! ESP_PER_SOC_TCP_WND
#if LWIP_TCP
#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN(0))
#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SND_BUF(0) < (2 * TCP_MSS)
#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SND_QUEUELEN(0) < (2 * (TCP_SND_BUF(0) / TCP_MSS))
#error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF(0)/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SNDLOWAT >= TCP_SND_BUF(0)
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS))
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!"
#endif
#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN(0)
#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#endif
#if !MEMP_MEM_MALLOC && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if ! ESP_LWIP
#if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))))
#error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_WND < TCP_MSS
#error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#endif
#endif /* LWIP_TCP */
#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */
#endif
/**
* Initialize all modules.
*/
void
lwip_init(void)
{
/* Modules initialization */
stats_init();
#if !NO_SYS
sys_init();
#endif /* !NO_SYS */
mem_init();
memp_init();
pbuf_init();
netif_init();
#if LWIP_IPV4
ip_init();
#if LWIP_ARP
etharp_init();
#endif /* LWIP_ARP */
#endif /* LWIP_IPV4 */
#if LWIP_RAW
raw_init();
#endif /* LWIP_RAW */
#if LWIP_UDP
udp_init();
#endif /* LWIP_UDP */
#if LWIP_TCP
tcp_init();
#endif /* LWIP_TCP */
#if LWIP_AUTOIP
autoip_init();
#endif /* LWIP_AUTOIP */
#if LWIP_IGMP
igmp_init();
#endif /* LWIP_IGMP */
#if LWIP_DNS
dns_init();
#endif /* LWIP_DNS */
#if PPP_SUPPORT
ppp_init();
#endif
#if LWIP_TIMERS
sys_timeouts_init();
#endif /* LWIP_TIMERS */
}

View file

@ -1,101 +0,0 @@
/**
* @file ip.c
* Common IPv4 and IPv6 code
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_IPV4 || LWIP_IPV6
#include "lwip/ip_addr.h"
#include "lwip/ip.h"
/** Global data for both IPv4 and IPv6 */
struct ip_globals ip_data;
#if LWIP_IPV4 && LWIP_IPV6
const ip_addr_t ip_addr_any_type = IPADDR_ANY_TYPE_INIT;
/** Convert IP address string (both versions) to numeric.
* The version is auto-detected from the string.
*
* @param cp IP address string to convert
* @param addr conversion result is stored here
* @return 1 on success, 0 on error
*/
int
ipaddr_aton(const char *cp, ip_addr_t *addr)
{
if (cp != NULL) {
const char* c;
for (c = cp; *c != 0; c++) {
if (*c == ':') {
/* contains a colon: IPv6 address */
if (addr) {
IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V6);
}
return ip6addr_aton(cp, ip_2_ip6(addr));
} else if (*c == '.') {
/* contains a dot: IPv4 address */
break;
}
}
/* call ip4addr_aton as fallback or if IPv4 was found */
if (addr) {
IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V4);
}
return ip4addr_aton(cp, ip_2_ip4(addr));
}
return 0;
}
/* If both IP versions are enabled, this function can dispatch packets to the correct one. */
err_t
ip_input(struct pbuf *p, struct netif *inp)
{
if (p != NULL) {
if (IP_HDR_GET_VERSION(p->payload) == 6) {
return ip6_input(p, inp);
}
return ip4_input(p, inp);
}
return ERR_VAL;
}
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#endif /* LWIP_IPV4 || LWIP_IPV6 */

View file

@ -1,551 +0,0 @@
/**
* @file
* AutoIP Automatic LinkLocal IP Configuration
*
*/
/*
*
* Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Dominik Spies <kontakt@dspies.de>
*
* This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
* with RFC 3927.
*
*
* Please coordinate changes and requests with Dominik Spies
* <kontakt@dspies.de>
*/
/*******************************************************************************
* USAGE:
*
* define LWIP_AUTOIP 1 in your lwipopts.h
*
* If you don't use tcpip.c (so, don't call, you don't call tcpip_init):
* - First, call autoip_init().
* - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces,
* that should be defined in autoip.h.
* I recommend a value of 100. The value must divide 1000 with a remainder almost 0.
* Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 ....
*
* Without DHCP:
* - Call autoip_start() after netif_add().
*
* With DHCP:
* - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h.
* - Configure your DHCP Client.
*
*/
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
#include "lwip/mem.h"
/* #include "lwip/udp.h" */
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/autoip.h"
#include "netif/etharp.h"
#include "lwip/dhcp.h"
#include <stdlib.h>
#include <string.h>
/* 169.254.0.0 */
#define AUTOIP_NET 0xA9FE0000
/* 169.254.1.0 */
#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)
/* 169.254.254.255 */
#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF)
/** Pseudo random macro based on netif informations.
* You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
#ifndef LWIP_AUTOIP_RAND
#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
((u32_t)((netif->hwaddr[4]) & 0xff))) + \
(netif->autoip?netif->autoip->tried_llipaddr:0))
#endif /* LWIP_AUTOIP_RAND */
/**
* Macro that generates the initial IP address to be tried by AUTOIP.
* If you want to override this, define it to something else in lwipopts.h.
*/
#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
/* static functions */
static void autoip_handle_arp_conflict(struct netif *netif);
/* creates a pseudo random LL IP-Address for a network interface */
static void autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr);
/* sends an ARP probe */
static err_t autoip_arp_probe(struct netif *netif);
/* sends an ARP announce */
static err_t autoip_arp_announce(struct netif *netif);
/* configure interface for use with current LL IP-Address */
static err_t autoip_bind(struct netif *netif);
/* start sending probes for llipaddr */
static void autoip_start_probing(struct netif *netif);
/** Set a statically allocated struct autoip to work with.
* Using this prevents autoip_start to allocate it using mem_malloc.
*
* @param netif the netif for which to set the struct autoip
* @param dhcp (uninitialised) dhcp struct allocated by the application
*/
void
autoip_set_struct(struct netif *netif, struct autoip *autoip)
{
LWIP_ASSERT("netif != NULL", netif != NULL);
LWIP_ASSERT("autoip != NULL", autoip != NULL);
LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL);
/* clear data structure */
memset(autoip, 0, sizeof(struct autoip));
/* autoip->state = AUTOIP_STATE_OFF; */
netif->autoip = autoip;
}
/** Restart AutoIP client and check the next address (conflict detected)
*
* @param netif The netif under AutoIP control
*/
static void
autoip_restart(struct netif *netif)
{
netif->autoip->tried_llipaddr++;
autoip_start(netif);
}
/**
* Handle a IP address conflict after an ARP conflict detection
*/
static void
autoip_handle_arp_conflict(struct netif *netif)
{
/* Somehow detect if we are defending or retreating */
unsigned char defend = 1; /* tbd */
if (defend) {
if (netif->autoip->lastconflict > 0) {
/* retreat, there was a conflicting ARP in the last
* DEFEND_INTERVAL seconds
*/
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
/* TODO: close all TCP sessions */
autoip_restart(netif);
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
autoip_arp_announce(netif);
netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
/* TODO: close all TCP sessions */
autoip_restart(netif);
}
}
/**
* Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
*
* @param netif network interface on which create the IP-Address
* @param ipaddr ip address to initialize
*/
static void
autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr)
{
/* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
* compliant to RFC 3927 Section 2.1
* We have 254 * 256 possibilities */
u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
addr += netif->autoip->tried_llipaddr;
addr = AUTOIP_NET | (addr & 0xffff);
/* Now, 169.254.0.0 <= addr <= 169.254.255.255 */
if (addr < AUTOIP_RANGE_START) {
addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
}
if (addr > AUTOIP_RANGE_END) {
addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
}
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
(addr <= AUTOIP_RANGE_END));
ip4_addr_set_u32(ipaddr, htonl(addr));
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
(u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
}
/**
* Sends an ARP probe from a network interface
*
* @param netif network interface used to send the probe
*/
static err_t
autoip_arp_probe(struct netif *netif)
{
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
(struct eth_addr *)netif->hwaddr, IP4_ADDR_ANY, &ethzero,
&netif->autoip->llipaddr, ARP_REQUEST);
}
/**
* Sends an ARP announce from a network interface
*
* @param netif network interface used to send the announce
*/
static err_t
autoip_arp_announce(struct netif *netif)
{
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
(struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, &ethzero,
&netif->autoip->llipaddr, ARP_REQUEST);
}
/**
* Configure interface for use with current LL IP-Address
*
* @param netif network interface to configure with current LL IP-Address
*/
static err_t
autoip_bind(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
ip4_addr_t sn_mask, gw_addr;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
(void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
IP4_ADDR(&sn_mask, 255, 255, 0, 0);
IP4_ADDR(&gw_addr, 0, 0, 0, 0);
netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
/* interface is used by routing now that an address is set */
#if ESP_LWIP
struct dhcp *dhcp = netif->dhcp;
if (dhcp->cb != NULL) {
dhcp->cb(netif);
}
#endif
return ERR_OK;
}
/**
* Start AutoIP client
*
* @param netif network interface on which start the AutoIP client
*/
err_t
autoip_start(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
err_t result = ERR_OK;
LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
/* Set IP-Address, Netmask and Gateway to 0 to make sure that
* ARP Packets are formed correctly
*/
netif_set_addr(netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0],
netif->name[1], (u16_t)netif->num));
if (autoip == NULL) {
/* no AutoIP client attached yet? */
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): starting new AUTOIP client\n"));
autoip = (struct autoip *)mem_malloc(sizeof(struct autoip));
if (autoip == NULL) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): could not allocate autoip\n"));
return ERR_MEM;
}
memset(autoip, 0, sizeof(struct autoip));
/* store this AutoIP client in the netif */
netif->autoip = autoip;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
} else {
autoip->state = AUTOIP_STATE_OFF;
autoip->ttw = 0;
autoip->sent_num = 0;
ip4_addr_set_zero(&autoip->llipaddr);
autoip->lastconflict = 0;
}
autoip_create_addr(netif, &(autoip->llipaddr));
autoip_start_probing(netif);
return result;
}
static void
autoip_start_probing(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
autoip->state = AUTOIP_STATE_PROBING;
autoip->sent_num = 0;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
/* time to wait to first probe, this is randomly
* chosen out of 0 to PROBE_WAIT seconds.
* compliant to RFC 3927 Section 2.2.1
*/
autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
/*
* if we tried more then MAX_CONFLICTS we must limit our rate for
* acquiring and probing address
* compliant to RFC 3927 Section 2.2.1
*/
if (autoip->tried_llipaddr > MAX_CONFLICTS) {
autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
}
/**
* Handle a possible change in the network configuration.
*
* If there is an AutoIP address configured, take the interface down
* and begin probing with the same address.
*/
void
autoip_network_changed(struct netif *netif)
{
if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
autoip_start_probing(netif);
}
}
/**
* Stop AutoIP client
*
* @param netif network interface on which stop the AutoIP client
*/
err_t
autoip_stop(struct netif *netif)
{
if (netif->autoip) {
netif->autoip->state = AUTOIP_STATE_OFF;
if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
netif_set_addr(netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
}
}
return ERR_OK;
}
/**
* Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
*/
void
autoip_tmr(void)
{
struct netif *netif = netif_list;
/* loop through netif's */
while (netif != NULL) {
/* only act on AutoIP configured interfaces */
if (netif->autoip != NULL) {
if (netif->autoip->lastconflict > 0) {
netif->autoip->lastconflict--;
}
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
(u16_t)(netif->autoip->state), netif->autoip->ttw));
switch(netif->autoip->state) {
case AUTOIP_STATE_PROBING:
if (netif->autoip->ttw > 0) {
netif->autoip->ttw--;
} else {
if (netif->autoip->sent_num >= PROBE_NUM) {
netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
netif->autoip->sent_num = 0;
netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
} else {
autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++;
/* calculate time to wait to next probe */
netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
}
}
break;
case AUTOIP_STATE_ANNOUNCING:
if (netif->autoip->ttw > 0) {
netif->autoip->ttw--;
} else {
if (netif->autoip->sent_num == 0) {
/* We are here the first time, so we waited ANNOUNCE_WAIT seconds
* Now we can bind to an IP address and use it.
*
* autoip_bind calls netif_set_addr. This triggers a gratuitous ARP
* which counts as an announcement.
*/
autoip_bind(netif);
} else {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() ANNOUNCING Sent Announce\n"));
}
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
netif->autoip->sent_num++;
if (netif->autoip->sent_num >= ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
}
}
break;
default:
/* nothing to do in other states */
break;
}
}
/* proceed to next network interface */
netif = netif->next;
}
}
/**
* Handles every incoming ARP Packet, called by etharp_arp_input.
*
* @param netif network interface to use for autoip processing
* @param hdr Incoming ARP packet
*/
void
autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
{
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) {
/* when ip.src == llipaddr && hw.src != netif->hwaddr
*
* when probing ip.dst == llipaddr && hw.src != netif->hwaddr
* we have a conflict and must solve it
*/
ip4_addr_t sipaddr, dipaddr;
struct eth_addr netifaddr;
ETHADDR16_COPY(netifaddr.addr, netif->hwaddr);
/* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without
* structure packing (not using structure copy which breaks strict-aliasing rules).
*/
IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
(netif->autoip->sent_num == 0))) {
/* RFC 3927 Section 2.2.1:
* from beginning to after ANNOUNCE_WAIT
* seconds we have a conflict if
* ip.src == llipaddr OR
* ip.dst == llipaddr && hw.src != own hwaddr
*/
if ((ip4_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
(ip4_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Probe Conflict detected\n"));
autoip_restart(netif);
}
} else {
/* RFC 3927 Section 2.5:
* in any state we have a conflict if
* ip.src == llipaddr && hw.src != own hwaddr
*/
if (ip4_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
autoip_handle_arp_conflict(netif);
}
}
}
}
/** check if AutoIP supplied netif->ip_addr
*
* @param netif the netif to check
* @return 1 if AutoIP supplied netif->ip_addr (state BOUND),
* 0 otherwise
*/
u8_t
autoip_supplied_address(struct netif *netif)
{
if ((netif != NULL) && (netif->autoip != NULL)) {
if (netif->autoip->state == AUTOIP_STATE_BOUND) {
return 1;
}
}
return 0;
}
#endif /* LWIP_IPV4 && LWIP_AUTOIP */

File diff suppressed because it is too large Load diff

View file

@ -1,386 +0,0 @@
/**
* @file
* ICMP - Internet Control Message Protocol
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* Some ICMP messages should be passed to the transport protocols. This
is not implemented. */
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/icmp.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/def.h"
#include "lwip/stats.h"
#include <string.h>
/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
* used to modify and send a response packet (and to 1 if this is not the case,
* e.g. when link header is stripped of when receiving) */
#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
/* The amount of data from the original packet to return in a dest-unreachable */
#define ICMP_DEST_UNREACH_DATASIZE 8
static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
/**
* Processes ICMP input packets, called from ip_input().
*
* Currently only processes icmp echo requests and sends
* out the echo response.
*
* @param p the icmp echo request packet, p->payload pointing to the icmp header
* @param inp the netif on which this packet was received
*/
void
icmp_input(struct pbuf *p, struct netif *inp)
{
u8_t type;
#ifdef LWIP_DEBUG
u8_t code;
#endif /* LWIP_DEBUG */
struct icmp_echo_hdr *iecho;
const struct ip_hdr *iphdr_in;
s16_t hlen;
const ip4_addr_t* src;
ICMP_STATS_INC(icmp.recv);
MIB2_STATS_INC(mib2.icmpinmsgs);
iphdr_in = ip4_current_header();
hlen = IPH_HL(iphdr_in) * 4;
if (p->len < sizeof(u16_t)*2) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
goto lenerr;
}
type = *((u8_t *)p->payload);
#ifdef LWIP_DEBUG
code = *(((u8_t *)p->payload)+1);
#endif /* LWIP_DEBUG */
switch (type) {
case ICMP_ER:
/* This is OK, echo reply might have been parsed by a raw PCB
(as obviously, an echo request has been sent, too). */
MIB2_STATS_INC(mib2.icmpinechoreps);
break;
case ICMP_ECHO:
MIB2_STATS_INC(mib2.icmpinechos);
src = ip4_current_dest_addr();
/* multicast destination address? */
if (ip4_addr_ismulticast(ip4_current_dest_addr())) {
#if LWIP_MULTICAST_PING
/* For multicast, use address of receiving interface as source address */
src = netif_ip4_addr(inp);
#else /* LWIP_MULTICAST_PING */
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n"));
goto icmperr;
#endif /* LWIP_MULTICAST_PING */
}
/* broadcast destination address? */
if (ip4_addr_isbroadcast(ip4_current_dest_addr(), ip_current_netif())) {
#if LWIP_BROADCAST_PING
/* For broadcast, use address of receiving interface as source address */
src = netif_ip4_addr(inp);
#else /* LWIP_BROADCAST_PING */
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n"));
goto icmperr;
#endif /* LWIP_BROADCAST_PING */
}
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
goto lenerr;
}
#if CHECKSUM_CHECK_ICMP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) {
if (inet_chksum_pbuf(p) != 0) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
pbuf_free(p);
ICMP_STATS_INC(icmp.chkerr);
MIB2_STATS_INC(mib2.icmpinerrors);
return;
}
}
#endif
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) {
/* p is not big enough to contain link headers
* allocate a new one and copy p into it
*/
struct pbuf *r;
/* allocate new packet buffer with space for link headers */
r = pbuf_alloc(PBUF_LINK, p->tot_len + hlen, PBUF_RAM);
if (r == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
goto icmperr;
}
LWIP_ASSERT("check that first pbuf can hold struct the ICMP header",
(r->len >= hlen + sizeof(struct icmp_echo_hdr)));
/* copy the ip header */
MEMCPY(r->payload, iphdr_in, hlen);
/* switch r->payload back to icmp header */
if (pbuf_header(r, -hlen)) {
LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0);
pbuf_free(r);
goto icmperr;
}
/* copy the rest of the packet without ip header */
if (pbuf_copy(r, p) != ERR_OK) {
LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0);
pbuf_free(r);
goto icmperr;
}
/* free the original p */
pbuf_free(p);
/* we now have an identical copy of p that has room for link headers */
p = r;
} else {
/* restore p->payload to point to icmp header */
if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) {
LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
goto icmperr;
}
}
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
/* At this point, all checks are OK. */
/* We generate an answer by switching the dest and src ip addresses,
* setting the icmp type to ECHO_RESPONSE and updating the checksum. */
iecho = (struct icmp_echo_hdr *)p->payload;
if (pbuf_header(p, hlen)) {
LWIP_ASSERT("Can't move over header in packet", 0);
} else {
err_t ret;
struct ip_hdr *iphdr = (struct ip_hdr*)p->payload;
ip4_addr_copy(iphdr->src, *src);
ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
ICMPH_TYPE_SET(iecho, ICMP_ER);
#if CHECKSUM_GEN_ICMP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) {
/* adjust the checksum */
if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1;
} else {
iecho->chksum += PP_HTONS(ICMP_ECHO << 8);
}
}
#if LWIP_CHECKSUM_CTRL_PER_NETIF
else {
iecho->chksum = 0;
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#else /* CHECKSUM_GEN_ICMP */
iecho->chksum = 0;
#endif /* CHECKSUM_GEN_ICMP */
/* Set the correct TTL and recalculate the header checksum. */
IPH_TTL_SET(iphdr, ICMP_TTL);
IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */
ICMP_STATS_INC(icmp.xmit);
/* increase number of messages attempted to send */
MIB2_STATS_INC(mib2.icmpoutmsgs);
/* increase number of echo replies attempted to send */
MIB2_STATS_INC(mib2.icmpoutechoreps);
/* send an ICMP packet */
ret = ip4_output_if(p, src, IP_HDRINCL,
ICMP_TTL, 0, IP_PROTO_ICMP, inp);
if (ret != ERR_OK) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret)));
}
}
break;
default:
if (type == ICMP_DUR) {
MIB2_STATS_INC(mib2.icmpindestunreachs);
} else if (type == ICMP_TE) {
MIB2_STATS_INC(mib2.icmpindestunreachs);
} else if (type == ICMP_PP) {
MIB2_STATS_INC(mib2.icmpinparmprobs);
} else if (type == ICMP_SQ) {
MIB2_STATS_INC(mib2.icmpinsrcquenchs);
} else if (type == ICMP_RD) {
MIB2_STATS_INC(mib2.icmpinredirects);
} else if (type == ICMP_TS) {
MIB2_STATS_INC(mib2.icmpintimestamps);
} else if (type == ICMP_TSR) {
MIB2_STATS_INC(mib2.icmpintimestampreps);
} else if (type == ICMP_AM) {
MIB2_STATS_INC(mib2.icmpinaddrmasks);
} else if (type == ICMP_AMR) {
MIB2_STATS_INC(mib2.icmpinaddrmaskreps);
}
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n",
(s16_t)type, (s16_t)code));
ICMP_STATS_INC(icmp.proterr);
ICMP_STATS_INC(icmp.drop);
}
pbuf_free(p);
return;
lenerr:
pbuf_free(p);
ICMP_STATS_INC(icmp.lenerr);
MIB2_STATS_INC(mib2.icmpinerrors);
return;
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING
icmperr:
pbuf_free(p);
ICMP_STATS_INC(icmp.err);
MIB2_STATS_INC(mib2.icmpinerrors);
return;
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */
}
/**
* Send an icmp 'destination unreachable' packet, called from ip_input() if
* the transport layer protocol is unknown and from udp_input() if the local
* port is not bound.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IP header
* @param t type of the 'unreachable' packet
*/
void
icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
{
MIB2_STATS_INC(mib2.icmpoutdestunreachs);
icmp_send_response(p, ICMP_DUR, t);
}
#if IP_FORWARD || IP_REASSEMBLY
/**
* Send a 'time exceeded' packet, called from ip_forward() if TTL is 0.
*
* @param p the input packet for which the 'time exceeded' should be sent,
* p->payload pointing to the IP header
* @param t type of the 'time exceeded' packet
*/
void
icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
{
MIB2_STATS_INC(mib2.icmpouttimeexcds);
icmp_send_response(p, ICMP_TE, t);
}
#endif /* IP_FORWARD || IP_REASSEMBLY */
/**
* Send an icmp packet in response to an incoming packet.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IP header
* @param type Type of the ICMP header
* @param code Code of the ICMP header
*/
static void
icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
{
struct pbuf *q;
struct ip_hdr *iphdr;
/* we can use the echo header here */
struct icmp_echo_hdr *icmphdr;
ip4_addr_t iphdr_src;
struct netif *netif;
/* increase number of messages attempted to send */
MIB2_STATS_INC(mib2.icmpoutmsgs);
/* ICMP header + IP header + 8 bytes of data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
PBUF_RAM);
if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
MIB2_STATS_INC(mib2.icmpouterrors);
return;
}
LWIP_ASSERT("check that first pbuf can hold icmp message",
(q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
iphdr = (struct ip_hdr *)p->payload;
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->src);
LWIP_DEBUGF(ICMP_DEBUG, (" to "));
ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->dest);
LWIP_DEBUGF(ICMP_DEBUG, ("\n"));
icmphdr = (struct icmp_echo_hdr *)q->payload;
icmphdr->type = type;
icmphdr->code = code;
icmphdr->id = 0;
icmphdr->seqno = 0;
/* copy fields from original packet */
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
ip4_addr_copy(iphdr_src, iphdr->src);
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
{
ip4_addr_t iphdr_dst;
ip4_addr_copy(iphdr_dst, iphdr->dest);
netif = ip4_route_src(&iphdr_src, &iphdr_dst);
}
#else
netif = ip4_route(&iphdr_src);
#endif
if (netif != NULL) {
/* calculate checksum */
icmphdr->chksum = 0;
#if CHECKSUM_GEN_ICMP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {
icmphdr->chksum = inet_chksum(icmphdr, q->len);
}
#endif
ICMP_STATS_INC(icmp.xmit);
ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif);
}
pbuf_free(q);
}
#endif /* LWIP_IPV4 && LWIP_ICMP */

View file

@ -1,827 +0,0 @@
/**
* @file
* IGMP - Internet Group Management Protocol
*
*/
/*
* Copyright (c) 2002 CITEL Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is a contribution to the lwIP TCP/IP stack.
* The Swedish Institute of Computer Science and Adam Dunkels
* are specifically granted permission to redistribute this
* source code.
*/
/*-------------------------------------------------------------
Note 1)
Although the rfc requires V1 AND V2 capability
we will only support v2 since now V1 is very old (August 1989)
V1 can be added if required
a debug print and statistic have been implemented to
show this up.
-------------------------------------------------------------
-------------------------------------------------------------
Note 2)
A query for a specific group address (as opposed to ALLHOSTS)
has now been implemented as I am unsure if it is required
a debug print and statistic have been implemented to
show this up.
-------------------------------------------------------------
-------------------------------------------------------------
Note 3)
The router alert rfc 2113 is implemented in outgoing packets
but not checked rigorously incoming
-------------------------------------------------------------
Steve Reynolds
------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
* RFC 988 - Host extensions for IP multicasting - V0
* RFC 1054 - Host extensions for IP multicasting -
* RFC 1112 - Host extensions for IP multicasting - V1
* RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard)
* RFC 3376 - Internet Group Management Protocol, Version 3 - V3
* RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+
* RFC 2113 - IP Router Alert Option -
*----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
* Includes
*----------------------------------------------------------------------------*/
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/igmp.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/ip.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "string.h"
/*
* IGMP constants
*/
#define IGMP_TTL 1
#define IGMP_MINLEN 8
#define ROUTER_ALERT 0x9404U
#define ROUTER_ALERTLEN 4
/*
* IGMP message types, including version number.
*/
#define IGMP_MEMB_QUERY 0x11 /* Membership query */
#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */
#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */
#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */
/* Group membership states */
#define IGMP_GROUP_NON_MEMBER 0
#define IGMP_GROUP_DELAYING_MEMBER 1
#define IGMP_GROUP_IDLE_MEMBER 2
/**
* IGMP packet format.
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct igmp_msg {
PACK_STRUCT_FLD_8(u8_t igmp_msgtype);
PACK_STRUCT_FLD_8(u8_t igmp_maxresp);
PACK_STRUCT_FIELD(u16_t igmp_checksum);
PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_group_address);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr);
static err_t igmp_remove_group(struct igmp_group *group);
static void igmp_timeout( struct igmp_group *group);
static void igmp_start_timer(struct igmp_group *group, u8_t max_time);
static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp);
static err_t igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif);
static void igmp_send(struct igmp_group *group, u8_t type);
static struct igmp_group* igmp_group_list;
static ip4_addr_t allsystems;
static ip4_addr_t allrouters;
/**
* Initialize the IGMP module
*/
void
igmp_init(void)
{
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n"));
IP4_ADDR(&allsystems, 224, 0, 0, 1);
IP4_ADDR(&allrouters, 224, 0, 0, 2);
}
/**
* Start IGMP processing on interface
*
* @param netif network interface on which start IGMP processing
*/
err_t
igmp_start(struct netif *netif)
{
struct igmp_group* group;
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", (void*)netif));
group = igmp_lookup_group(netif, &allsystems);
if (group != NULL) {
group->group_state = IGMP_GROUP_IDLE_MEMBER;
group->use++;
/* Allow the igmp messages at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD "));
ip4_addr_debug_print_val(IGMP_DEBUG, allsystems);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif));
netif->igmp_mac_filter(netif, &allsystems, IGMP_ADD_MAC_FILTER);
}
return ERR_OK;
}
return ERR_MEM;
}
/**
* Stop IGMP processing on interface
*
* @param netif network interface on which stop IGMP processing
*/
err_t
igmp_stop(struct netif *netif)
{
struct igmp_group *group = igmp_group_list;
struct igmp_group *prev = NULL;
struct igmp_group *next;
/* look for groups joined on this interface further down the list */
while (group != NULL) {
next = group->next;
/* is it a group joined on this interface? */
if (group->netif == netif) {
/* is it the first group of the list? */
if (group == igmp_group_list) {
igmp_group_list = next;
}
/* is there a "previous" group defined? */
if (prev != NULL) {
prev->next = next;
}
/* disable the group at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL "));
ip4_addr_debug_print(IGMP_DEBUG, &group->group_address);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif));
netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER);
}
/* free group */
memp_free(MEMP_IGMP_GROUP, group);
} else {
/* change the "previous" */
prev = group;
}
/* move to "next" */
group = next;
}
return ERR_OK;
}
/**
* Report IGMP memberships for this interface
*
* @param netif network interface on which report IGMP memberships
*/
void
igmp_report_groups(struct netif *netif)
{
struct igmp_group *group = igmp_group_list;
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", (void*)netif));
while (group != NULL) {
if ((group->netif == netif) && (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
}
group = group->next;
}
}
/**
* Search for a group in the global igmp_group_list
*
* @param ifp the network interface for which to look
* @param addr the group ip address to search for
* @return a struct igmp_group* if the group has been found,
* NULL if the group wasn't found.
*/
struct igmp_group *
igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr)
{
struct igmp_group *group = igmp_group_list;
while (group != NULL) {
if ((group->netif == ifp) && (ip4_addr_cmp(&(group->group_address), addr))) {
return group;
}
group = group->next;
}
/* to be clearer, we return NULL here instead of
* 'group' (which is also NULL at this point).
*/
return NULL;
}
/**
* Search for a specific igmp group and create a new one if not found-
*
* @param ifp the network interface for which to look
* @param addr the group ip address to search
* @return a struct igmp_group*,
* NULL on memory error.
*/
struct igmp_group *
igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
{
struct igmp_group *group;
/* Search if the group already exists */
group = igmp_lookfor_group(ifp, addr);
if (group != NULL) {
/* Group already exists. */
return group;
}
/* Group doesn't exist yet, create a new one */
group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
if (group != NULL) {
group->netif = ifp;
ip4_addr_set(&(group->group_address), addr);
group->timer = 0; /* Not running */
group->group_state = IGMP_GROUP_NON_MEMBER;
group->last_reporter_flag = 0;
group->use = 0;
group->next = igmp_group_list;
igmp_group_list = group;
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to ")));
ip4_addr_debug_print(IGMP_DEBUG, addr);
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)ifp));
return group;
}
/**
* Remove a group in the global igmp_group_list
*
* @param group the group to remove from the global igmp_group_list
* @return ERR_OK if group was removed from the list, an err_t otherwise
*/
static err_t
igmp_remove_group(struct igmp_group *group)
{
err_t err = ERR_OK;
/* Is it the first group? */
if (igmp_group_list == group) {
igmp_group_list = group->next;
} else {
/* look for group further down the list */
struct igmp_group *tmpGroup;
for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) {
if (tmpGroup->next == group) {
tmpGroup->next = group->next;
break;
}
}
/* Group not found in the global igmp_group_list */
if (tmpGroup == NULL) {
err = ERR_ARG;
}
}
/* free group */
memp_free(MEMP_IGMP_GROUP, group);
return err;
}
/**
* Called from ip_input() if a new IGMP packet is received.
*
* @param p received igmp packet, p->payload pointing to the igmp header
* @param inp network interface on which the packet was received
* @param dest destination ip address of the igmp packet
*/
void
igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
{
struct igmp_msg* igmp;
struct igmp_group* group;
struct igmp_group* groupref;
IGMP_STATS_INC(igmp.recv);
/* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */
if (p->len < IGMP_MINLEN) {
pbuf_free(p);
IGMP_STATS_INC(igmp.lenerr);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n"));
return;
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from "));
ip4_addr_debug_print(IGMP_DEBUG, &(ip4_current_header()->src));
LWIP_DEBUGF(IGMP_DEBUG, (" to address "));
ip4_addr_debug_print(IGMP_DEBUG, &(ip4_current_header()->dest));
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)inp));
/* Now calculate and check the checksum */
igmp = (struct igmp_msg *)p->payload;
if (inet_chksum(igmp, p->len)) {
pbuf_free(p);
IGMP_STATS_INC(igmp.chkerr);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n"));
return;
}
/* Packet is ok so find an existing group */
group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */
/* If group can be found or create... */
if (!group) {
pbuf_free(p);
IGMP_STATS_INC(igmp.drop);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
return;
}
/* NOW ACT ON THE INCOMING MESSAGE TYPE... */
switch (igmp->igmp_msgtype) {
case IGMP_MEMB_QUERY:
/* IGMP_MEMB_QUERY to the "all systems" address ? */
if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) {
/* THIS IS THE GENERAL QUERY */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
if (igmp->igmp_maxresp == 0) {
IGMP_STATS_INC(igmp.rx_v1);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
} else {
IGMP_STATS_INC(igmp.rx_general);
}
groupref = igmp_group_list;
while (groupref) {
/* Do not send messages on the all systems group address! */
if ((groupref->netif == inp) && (!(ip4_addr_cmp(&(groupref->group_address), &allsystems)))) {
igmp_delaying_member(groupref, igmp->igmp_maxresp);
}
groupref = groupref->next;
}
} else {
/* IGMP_MEMB_QUERY to a specific group ? */
if (!ip4_addr_isany(&igmp->igmp_group_address)) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group "));
ip4_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address);
if (ip4_addr_cmp(dest, &allsystems)) {
ip4_addr_t groupaddr;
LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
/* we first need to re-look for the group since we used dest last time */
ip4_addr_copy(groupaddr, igmp->igmp_group_address);
group = igmp_lookfor_group(inp, &groupaddr);
} else {
LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
}
if (group != NULL) {
IGMP_STATS_INC(igmp.rx_group);
igmp_delaying_member(group, igmp->igmp_maxresp);
} else {
IGMP_STATS_INC(igmp.drop);
}
} else {
IGMP_STATS_INC(igmp.proterr);
}
}
break;
case IGMP_V2_MEMB_REPORT:
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
IGMP_STATS_INC(igmp.rx_report);
if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
/* This is on a specific group we have already looked up */
group->timer = 0; /* stopped */
group->group_state = IGMP_GROUP_IDLE_MEMBER;
group->last_reporter_flag = 0;
}
break;
default:
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n",
igmp->igmp_msgtype, group->group_state, (void*)&group, (void*)group->netif));
IGMP_STATS_INC(igmp.proterr);
break;
}
pbuf_free(p);
return;
}
/**
* Join a group on one network interface.
*
* @param ifaddr ip address of the network interface which should join a new group
* @param groupaddr the ip address of the group which to join
* @return ERR_OK if group was joined on the netif(s), an err_t otherwise
*/
err_t
igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct netif *netif;
/* make sure it is multicast address */
LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* loop through netif's */
netif = netif_list;
while (netif != NULL) {
/* Should we join this interface ? */
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
err = igmp_joingroup_netif(netif, groupaddr);
if (err != ERR_OK) {
/* Return an error even if some network interfaces are joined */
/** @todo undo any other netif already joined */
return err;
}
}
/* proceed to next network interface */
netif = netif->next;
}
return err;
}
/**
* Join a group on one network interface.
*
* @param netif the network interface which should join a new group
* @param groupaddr the ip address of the group which to join
* @return ERR_OK if group was joined on the netif, an err_t otherwise
*/
err_t
igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
{
struct igmp_group *group;
/* make sure it is multicast address */
LWIP_ERROR("igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* make sure it is an igmp-enabled netif */
LWIP_ERROR("igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
/* find group or create a new one if not found */
group = igmp_lookup_group(netif, groupaddr);
if (group != NULL) {
/* This should create a new group, check the state to make sure */
if (group->group_state != IGMP_GROUP_NON_MEMBER) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to group not in state IGMP_GROUP_NON_MEMBER\n"));
} else {
/* OK - it was new group */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to new group: "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
/* If first use of the group, allow the group at the MAC level */
if ((group->use==0) && (netif->igmp_mac_filter != NULL)) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: igmp_mac_filter(ADD "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif));
netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER);
}
IGMP_STATS_INC(igmp.tx_join);
igmp_send(group, IGMP_V2_MEMB_REPORT);
igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
/* Need to work out where this timer comes from */
group->group_state = IGMP_GROUP_DELAYING_MEMBER;
}
/* Increment group use */
group->use++;
/* Join on this interface */
return ERR_OK;
} else {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: Not enough memory to join to group\n"));
return ERR_MEM;
}
}
/**
* Leave a group on one network interface.
*
* @param ifaddr ip address of the network interface which should leave a group
* @param groupaddr the ip address of the group which to leave
* @return ERR_OK if group was left on the netif(s), an err_t otherwise
*/
err_t
igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct netif *netif;
/* make sure it is multicast address */
LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* loop through netif's */
netif = netif_list;
while (netif != NULL) {
/* Should we leave this interface ? */
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
err_t res = igmp_leavegroup_netif(netif, groupaddr);
if (err != ERR_OK) {
/* Store this result if we have not yet gotten a success */
err = res;
}
}
/* proceed to next network interface */
netif = netif->next;
}
return err;
}
/**
* Leave a group on one network interface.
*
* @param netif the network interface which should leave a group
* @param groupaddr the ip address of the group which to leave
* @return ERR_OK if group was left on the netif, an err_t otherwise
*/
err_t
igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
{
struct igmp_group *group;
/* make sure it is multicast address */
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* make sure it is an igmp-enabled netif */
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
/* find group */
group = igmp_lookfor_group(netif, groupaddr);
if (group != NULL) {
/* Only send a leave if the flag is set according to the state diagram */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: Leaving group: "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
/* If there is no other use of the group */
if (group->use <= 1) {
/* If we are the last reporter for this group */
if (group->last_reporter_flag) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: sending leaving group\n"));
IGMP_STATS_INC(igmp.tx_leave);
igmp_send(group, IGMP_LEAVE_GROUP);
}
/* Disable the group at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: igmp_mac_filter(DEL "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif));
netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER);
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: remove group: "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
/* Free the group */
igmp_remove_group(group);
} else {
/* Decrement group use */
group->use--;
}
return ERR_OK;
} else {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: not member of group\n"));
return ERR_VAL;
}
}
/**
* The igmp timer function (both for NO_SYS=1 and =0)
* Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default).
*/
void
igmp_tmr(void)
{
struct igmp_group *group = igmp_group_list;
while (group != NULL) {
if (group->timer > 0) {
group->timer--;
if (group->timer == 0) {
igmp_timeout(group);
}
}
group = group->next;
}
}
/**
* Called if a timeout for one group is reached.
* Sends a report for this group.
*
* @param group an igmp_group for which a timeout is reached
*/
static void
igmp_timeout(struct igmp_group *group)
{
/* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group
(unless it is the allsystems group) */
if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
(!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address "));
ip4_addr_debug_print(IGMP_DEBUG, &(group->group_address));
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)group->netif));
IGMP_STATS_INC(igmp.tx_report);
igmp_send(group, IGMP_V2_MEMB_REPORT);
}
}
/**
* Start a timer for an igmp group
*
* @param group the igmp_group for which to start a timer
* @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with
* every call to igmp_tmr())
*/
static void
igmp_start_timer(struct igmp_group *group, u8_t max_time)
{
#ifdef LWIP_RAND
group->timer = max_time > 2 ? (LWIP_RAND() % max_time) : 1;
#else /* LWIP_RAND */
/* ATTENTION: use this only if absolutely necessary! */
group->timer = max_time / 2;
#endif /* LWIP_RAND */
if (group->timer == 0) {
group->timer = 1;
}
}
/**
* Delaying membership report for a group if necessary
*
* @param group the igmp_group for which "delaying" membership report
* @param maxresp query delay
*/
static void
igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
{
if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) ||
((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
((group->timer == 0) || (maxresp < group->timer)))) {
igmp_start_timer(group, maxresp);
group->group_state = IGMP_GROUP_DELAYING_MEMBER;
}
}
/**
* Sends an IP packet on a network interface. This function constructs the IP header
* and calculates the IP header checksum. If the source IP address is NULL,
* the IP address of the outgoing network interface is filled in as source address.
*
* @param p the packet to send (p->payload points to the data, e.g. next
protocol header; if dest == IP_HDRINCL, p already includes an IP
header and p->payload points to that IP header)
* @param src the source IP address to send from (if src == IP_ADDR_ANY, the
* IP address of the netif used to send is used as source address)
* @param dest the destination IP address to send the packet to
* @param ttl the TTL value to be set in the IP header
* @param proto the PROTOCOL to be set in the IP header
* @param netif the netif on which to send this packet
* @return ERR_OK if the packet was sent OK
* ERR_BUF if p doesn't have enough space for IP/LINK headers
* returns errors returned by netif->output
*/
static err_t
igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif)
{
/* This is the "router alert" option */
u16_t ra[2];
ra[0] = PP_HTONS(ROUTER_ALERT);
ra[1] = 0x0000; /* Router shall examine packet */
IGMP_STATS_INC(igmp.xmit);
return ip4_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN);
}
/**
* Send an igmp packet to a specific group.
*
* @param group the group to which to send the packet
* @param type the type of igmp packet to send
*/
static void
igmp_send(struct igmp_group *group, u8_t type)
{
struct pbuf* p = NULL;
struct igmp_msg* igmp = NULL;
ip4_addr_t src = *IP4_ADDR_ANY;
ip4_addr_t* dest = NULL;
/* IP header + "router alert" option + IGMP header */
p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM);
if (p) {
igmp = (struct igmp_msg *)p->payload;
LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg",
(p->len >= sizeof(struct igmp_msg)));
ip4_addr_copy(src, *netif_ip4_addr(group->netif));
if (type == IGMP_V2_MEMB_REPORT) {
dest = &(group->group_address);
ip4_addr_copy(igmp->igmp_group_address, group->group_address);
group->last_reporter_flag = 1; /* Remember we were the last to report */
} else {
if (type == IGMP_LEAVE_GROUP) {
dest = &allrouters;
ip4_addr_copy(igmp->igmp_group_address, group->group_address);
}
}
if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) {
igmp->igmp_msgtype = type;
igmp->igmp_maxresp = 0;
igmp->igmp_checksum = 0;
igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN);
igmp_ip_output_if(p, &src, dest, group->netif);
}
pbuf_free(p);
} else {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n"));
IGMP_STATS_INC(igmp.memerr);
}
}
#endif /* LWIP_IPV4 && LWIP_IGMP */

File diff suppressed because it is too large Load diff

View file

@ -1,362 +0,0 @@
/**
* @file
* This is the IPv4 address tools implementation.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_IPV4
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST);
/**
* Determine if an address is a broadcast address on a network interface
*
* @param addr address to be checked
* @param netif the network interface against which the address is checked
* @return returns non-zero if the address is a broadcast address
*/
u8_t ESP_IRAM_ATTR
ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
{
ip4_addr_t ipaddr;
ip4_addr_set_u32(&ipaddr, addr);
/* all ones (broadcast) or all zeroes (old skool broadcast) */
if ((~addr == IPADDR_ANY) ||
(addr == IPADDR_ANY)) {
return 1;
/* no broadcast support on this network interface? */
} else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
/* the given address cannot be a broadcast address
* nor can we check against any broadcast addresses */
return 0;
/* address matches network interface address exactly? => no broadcast */
} else if (addr == ip4_addr_get_u32(netif_ip4_addr(netif))) {
return 0;
/* on the same (sub) network... */
} else if (ip4_addr_netcmp(&ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif))
/* ...and host identifier bits are all ones? =>... */
&& ((addr & ~ip4_addr_get_u32(netif_ip4_netmask(netif))) ==
(IPADDR_BROADCAST & ~ip4_addr_get_u32(netif_ip4_netmask(netif))))) {
/* => network broadcast address */
return 1;
} else {
return 0;
}
}
/** Checks if a netmask is valid (starting with ones, then only zeros)
*
* @param netmask the IPv4 netmask to check (in network byte order!)
* @return 1 if the netmask is valid, 0 if it is not
*/
u8_t
ip4_addr_netmask_valid(u32_t netmask)
{
u32_t mask;
u32_t nm_hostorder = lwip_htonl(netmask);
/* first, check for the first zero */
for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
if ((nm_hostorder & mask) == 0) {
break;
}
}
/* then check that there is no one */
for (; mask != 0; mask >>= 1) {
if ((nm_hostorder & mask) != 0) {
/* there is a one after the first zero -> invalid */
return 0;
}
}
/* no one after the first zero -> valid */
return 1;
}
/* Here for now until needed in other places in lwIP */
#ifndef isprint
#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up)
#define isprint(c) in_range(c, 0x20, 0x7f)
#define isdigit(c) in_range(c, '0', '9')
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
#define islower(c) in_range(c, 'a', 'z')
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
#endif
/**
* Ascii internet address interpretation routine.
* The value returned is in network order.
*
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
* @return ip address in network order
*/
u32_t
ipaddr_addr(const char *cp)
{
ip4_addr_t val;
if (ip4addr_aton(cp, &val)) {
return ip4_addr_get_u32(&val);
}
return (IPADDR_NONE);
}
/**
* Check whether "cp" is a valid ascii representation
* of an Internet address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
* This replaces inet_addr, the return value from which
* cannot distinguish between failure and a local broadcast address.
*
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
* @param addr pointer to which to save the ip address in network order
* @return 1 if cp could be converted to addr, 0 on failure
*/
int
ip4addr_aton(const char *cp, ip4_addr_t *addr)
{
u32_t val;
u8_t base;
char c;
u32_t parts[4];
u32_t *pp = parts;
#if ESP_LWIP
//#if 0
char ch;
unsigned long cutoff;
int cutlim;
#endif
c = *cp;
for (;;) {
/*
* Collect number up to ``.''.
* Values are specified as for C:
* 0x=hex, 0=octal, 1-9=decimal.
*/
if (!isdigit(c)) {
return 0;
}
val = 0;
base = 10;
if (c == '0') {
c = *++cp;
if (c == 'x' || c == 'X') {
base = 16;
c = *++cp;
} else {
base = 8;
}
}
#if ESP_IP4_ATON
cutoff =(unsigned long)0xffffffff / (unsigned long)base;
cutlim =(unsigned long)0xffffffff % (unsigned long)base;
for (;;) {
if (isdigit(c)) {
ch = (int)(c - '0');
if (val > cutoff || (val == cutoff && ch > cutlim))
return (0);
val = (val * base) + (int)(c - '0');
c = *++cp;
} else if (base == 16 && isxdigit(c)) {
ch = (int)(c + 10 - (islower(c) ? 'a' : 'A'));
if (val > cutoff || (val == cutoff && ch > cutlim))
return (0);
val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
c = *++cp;
} else
break;
}
#else
for (;;) {
if (isdigit(c)) {
val = (val * base) + (int)(c - '0');
c = *++cp;
} else if (base == 16 && isxdigit(c)) {
val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
c = *++cp;
} else {
break;
}
}
#endif
if (c == '.') {
/*
* Internet format:
* a.b.c.d
* a.b.c (with c treated as 16 bits)
* a.b (with b treated as 24 bits)
*/
if (pp >= parts + 3) {
return 0;
}
*pp++ = val;
c = *++cp;
} else {
break;
}
}
/*
* Check for trailing characters.
*/
if (c != '\0' && !isspace(c)) {
return 0;
}
/*
* Concoct the address according to
* the number of parts specified.
*/
switch (pp - parts + 1) {
case 0:
return 0; /* initial nondigit */
case 1: /* a -- 32 bits */
break;
case 2: /* a.b -- 8.24 bits */
if (val > 0xffffffUL) {
return 0;
}
if (parts[0] > 0xff) {
return 0;
}
val |= parts[0] << 24;
break;
case 3: /* a.b.c -- 8.8.16 bits */
if (val > 0xffff) {
return 0;
}
if ((parts[0] > 0xff) || (parts[1] > 0xff)) {
return 0;
}
val |= (parts[0] << 24) | (parts[1] << 16);
break;
case 4: /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xff) {
return 0;
}
if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) {
return 0;
}
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
break;
default:
LWIP_ASSERT("unhandled", 0);
break;
}
if (addr) {
ip4_addr_set_u32(addr, htonl(val));
}
return 1;
}
/**
* Convert numeric IP address into decimal dotted ASCII representation.
* returns ptr to static buffer; not reentrant!
*
* @param addr ip address in network order to convert
* @return pointer to a global static (!) buffer that holds the ASCII
* representation of addr
*/
char*
ip4addr_ntoa(const ip4_addr_t *addr)
{
static char str[IP4ADDR_STRLEN_MAX];
return ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX);
}
/**
* Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
*
* @param addr ip address in network order to convert
* @param buf target buffer where the string is stored
* @param buflen length of buf
* @return either pointer to buf which now holds the ASCII
* representation of addr or NULL if buf was too small
*/
char*
ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
{
u32_t s_addr;
char inv[3];
char *rp;
u8_t *ap;
u8_t rem;
u8_t n;
u8_t i;
int len = 0;
s_addr = ip4_addr_get_u32(addr);
rp = buf;
ap = (u8_t *)&s_addr;
for (n = 0; n < 4; n++) {
i = 0;
do {
rem = *ap % (u8_t)10;
*ap /= (u8_t)10;
inv[i++] = '0' + rem;
} while (*ap);
while (i--) {
if (len++ >= buflen) {
return NULL;
}
*rp++ = inv[i];
}
if (len++ >= buflen) {
return NULL;
}
*rp++ = '.';
ap++;
}
*--rp = 0;
return buf;
}
#endif /* LWIP_IPV4 */

View file

@ -1,897 +0,0 @@
/**
* @file
* This is the IPv4 packet segmentation and reassembly implementation.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Jani Monoses <jani@iv.ro>
* Simon Goldschmidt
* original reassembly code by Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_IPV4
#include "lwip/ip_frag.h"
#include "lwip/def.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "lwip/icmp.h"
#include <string.h>
#if IP_REASSEMBLY
/**
* The IP reassembly code currently has the following limitations:
* - IP header options are not supported
* - fragments must not overlap (e.g. due to different routes),
* currently, overlapping or duplicate fragments are thrown away
* if IP_REASS_CHECK_OVERLAP=1 (the default)!
*
* @todo: work with IP header options
*/
/** Setting this to 0, you can turn off checking the fragments for overlapping
* regions. The code gets a little smaller. Only use this if you know that
* overlapping won't occur on your network! */
#ifndef IP_REASS_CHECK_OVERLAP
#define IP_REASS_CHECK_OVERLAP 1
#endif /* IP_REASS_CHECK_OVERLAP */
/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is
* full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller.
* Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA
* is set to 1, so one datagram can be reassembled at a time, only. */
#ifndef IP_REASS_FREE_OLDEST
#define IP_REASS_FREE_OLDEST 1
#endif /* IP_REASS_FREE_OLDEST */
#define IP_REASS_FLAG_LASTFRAG 0x01
/** This is a helper struct which holds the starting
* offset and the ending offset of this fragment to
* easily chain the fragments.
* It has the same packing requirements as the IP header, since it replaces
* the IP header in memory in incoming fragments (after copying it) to keep
* track of the various fragments. (-> If the IP header doesn't need packing,
* this struct doesn't need packing, too.)
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip_reass_helper {
PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
PACK_STRUCT_FIELD(u16_t start);
PACK_STRUCT_FIELD(u16_t end);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \
(ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \
ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0
/* global variables */
static struct ip_reassdata *reassdatagrams;
static u16_t ip_reass_pbufcount;
/* function prototypes */
static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
/**
* Reassembly timer base function
* for both NO_SYS == 0 and 1 (!).
*
* Should be called every 1000 msec (defined by IP_TMR_INTERVAL).
*/
void
ip_reass_tmr(void)
{
struct ip_reassdata *r, *prev = NULL;
r = reassdatagrams;
while (r != NULL) {
/* Decrement the timer. Once it reaches 0,
* clean up the incomplete fragment assembly */
if (r->timer > 0) {
r->timer--;
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer));
prev = r;
r = r->next;
} else {
/* reassembly timed out */
struct ip_reassdata *tmp;
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n"));
tmp = r;
/* get the next pointer before freeing */
r = r->next;
/* free the helper struct and all enqueued pbufs */
ip_reass_free_complete_datagram(tmp, prev);
}
}
}
/**
* Free a datagram (struct ip_reassdata) and all its pbufs.
* Updates the total count of enqueued pbufs (ip_reass_pbufcount),
* SNMP counters and sends an ICMP time exceeded packet.
*
* @param ipr datagram to free
* @param prev the previous datagram in the linked list
* @return the number of pbufs freed
*/
static int
ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
{
u16_t pbufs_freed = 0;
u8_t clen;
struct pbuf *p;
struct ip_reass_helper *iprh;
LWIP_ASSERT("prev != ipr", prev != ipr);
if (prev != NULL) {
LWIP_ASSERT("prev->next == ipr", prev->next == ipr);
}
MIB2_STATS_INC(mib2.ipreasmfails);
#if LWIP_ICMP
iprh = (struct ip_reass_helper *)ipr->p->payload;
if (iprh->start == 0) {
/* The first fragment was received, send ICMP time exceeded. */
/* First, de-queue the first pbuf from r->p. */
p = ipr->p;
ipr->p = iprh->next_pbuf;
/* Then, copy the original header into it. */
SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN);
icmp_time_exceeded(p, ICMP_TE_FRAG);
clen = pbuf_clen(p);
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
pbufs_freed += clen;
pbuf_free(p);
}
#endif /* LWIP_ICMP */
/* First, free all received pbufs. The individual pbufs need to be released
separately as they have not yet been chained */
p = ipr->p;
while (p != NULL) {
struct pbuf *pcur;
iprh = (struct ip_reass_helper *)p->payload;
pcur = p;
/* get the next pointer before freeing */
p = iprh->next_pbuf;
clen = pbuf_clen(pcur);
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
pbufs_freed += clen;
pbuf_free(pcur);
}
/* Then, unchain the struct ip_reassdata from the list and free it. */
ip_reass_dequeue_datagram(ipr, prev);
LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed);
ip_reass_pbufcount -= pbufs_freed;
return pbufs_freed;
}
#if IP_REASS_FREE_OLDEST
/**
* Free the oldest datagram to make room for enqueueing new fragments.
* The datagram 'fraghdr' belongs to is not freed!
*
* @param fraghdr IP header of the current fragment
* @param pbufs_needed number of pbufs needed to enqueue
* (used for freeing other datagrams if not enough space)
* @return the number of pbufs freed
*/
static int
ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
{
/* @todo Can't we simply remove the last datagram in the
* linked list behind reassdatagrams?
*/
struct ip_reassdata *r, *oldest, *prev, *oldest_prev;
int pbufs_freed = 0, pbufs_freed_current;
int other_datagrams;
/* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs,
* but don't free the datagram that 'fraghdr' belongs to! */
do {
oldest = NULL;
prev = NULL;
oldest_prev = NULL;
other_datagrams = 0;
r = reassdatagrams;
while (r != NULL) {
if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) {
/* Not the same datagram as fraghdr */
other_datagrams++;
if (oldest == NULL) {
oldest = r;
oldest_prev = prev;
} else if (r->timer <= oldest->timer) {
/* older than the previous oldest */
oldest = r;
oldest_prev = prev;
}
}
if (r->next != NULL) {
prev = r;
}
r = r->next;
}
if (oldest != NULL) {
pbufs_freed_current = ip_reass_free_complete_datagram(oldest, oldest_prev);
pbufs_freed += pbufs_freed_current;
}
} while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1));
return pbufs_freed;
}
#endif /* IP_REASS_FREE_OLDEST */
/**
* Enqueues a new fragment into the fragment queue
* @param fraghdr points to the new fragments IP hdr
* @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space)
* @return A pointer to the queue location into which the fragment was enqueued
*/
static struct ip_reassdata*
ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen)
{
struct ip_reassdata* ipr;
#if ! IP_REASS_FREE_OLDEST
LWIP_UNUSED_ARG(clen);
#endif
/* No matching previous fragment found, allocate a new reassdata struct */
ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
if (ipr == NULL) {
#if IP_REASS_FREE_OLDEST
if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) {
ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
}
if (ipr == NULL)
#endif /* IP_REASS_FREE_OLDEST */
{
IPFRAG_STATS_INC(ip_frag.memerr);
LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n"));
return NULL;
}
}
memset(ipr, 0, sizeof(struct ip_reassdata));
ipr->timer = IP_REASS_MAXAGE;
/* enqueue the new structure to the front of the list */
ipr->next = reassdatagrams;
reassdatagrams = ipr;
/* copy the ip header for later tests and input */
/* @todo: no ip options supported? */
SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN);
return ipr;
}
/**
* Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs.
* @param ipr points to the queue entry to dequeue
*/
static void
ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
{
/* dequeue the reass struct */
if (reassdatagrams == ipr) {
/* it was the first in the list */
reassdatagrams = ipr->next;
} else {
/* it wasn't the first, so it must have a valid 'prev' */
LWIP_ASSERT("sanity check linked list", prev != NULL);
prev->next = ipr->next;
}
/* now we can free the ip_reassdata struct */
memp_free(MEMP_REASSDATA, ipr);
}
/**
* Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list
* will grow over time as new pbufs are rx.
* Also checks that the datagram passes basic continuity checks (if the last
* fragment was received at least once).
* @param root_p points to the 'root' pbuf for the current datagram being assembled.
* @param new_p points to the pbuf for the current fragment
* @return 0 if invalid, >0 otherwise
*/
static int
ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p)
{
struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
struct pbuf *q;
u16_t offset,len;
struct ip_hdr *fraghdr;
int valid = 1;
/* Extract length and fragment offset from current fragment */
fraghdr = (struct ip_hdr*)new_p->payload;
len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
/* overwrite the fragment's ip header from the pbuf with our helper struct,
* and setup the embedded helper structure. */
/* make sure the struct ip_reass_helper fits into the IP header */
LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN",
sizeof(struct ip_reass_helper) <= IP_HLEN);
iprh = (struct ip_reass_helper*)new_p->payload;
iprh->next_pbuf = NULL;
iprh->start = offset;
iprh->end = offset + len;
/* Iterate through until we either get to the end of the list (append),
* or we find one with a larger offset (insert). */
for (q = ipr->p; q != NULL;) {
iprh_tmp = (struct ip_reass_helper*)q->payload;
if (iprh->start < iprh_tmp->start) {
/* the new pbuf should be inserted before this */
iprh->next_pbuf = q;
if (iprh_prev != NULL) {
/* not the fragment with the lowest offset */
#if IP_REASS_CHECK_OVERLAP
if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) {
/* fragment overlaps with previous or following, throw away */
goto freepbuf;
}
#endif /* IP_REASS_CHECK_OVERLAP */
iprh_prev->next_pbuf = new_p;
} else {
/* fragment with the lowest offset */
ipr->p = new_p;
}
break;
} else if (iprh->start == iprh_tmp->start) {
/* received the same datagram twice: no need to keep the datagram */
goto freepbuf;
#if IP_REASS_CHECK_OVERLAP
} else if (iprh->start < iprh_tmp->end) {
/* overlap: no need to keep the new datagram */
goto freepbuf;
#endif /* IP_REASS_CHECK_OVERLAP */
} else {
/* Check if the fragments received so far have no holes. */
if (iprh_prev != NULL) {
if (iprh_prev->end != iprh_tmp->start) {
/* There is a fragment missing between the current
* and the previous fragment */
valid = 0;
}
}
}
q = iprh_tmp->next_pbuf;
iprh_prev = iprh_tmp;
}
/* If q is NULL, then we made it to the end of the list. Determine what to do now */
if (q == NULL) {
if (iprh_prev != NULL) {
/* this is (for now), the fragment with the highest offset:
* chain it to the last fragment */
#if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start);
#endif /* IP_REASS_CHECK_OVERLAP */
iprh_prev->next_pbuf = new_p;
if (iprh_prev->end != iprh->start) {
valid = 0;
}
} else {
#if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("no previous fragment, this must be the first fragment!",
ipr->p == NULL);
#endif /* IP_REASS_CHECK_OVERLAP */
/* this is the first fragment we ever received for this ip datagram */
ipr->p = new_p;
}
}
/* At this point, the validation part begins: */
/* If we already received the last fragment */
if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) {
/* and had no holes so far */
if (valid) {
/* then check if the rest of the fragments is here */
/* Check if the queue starts with the first datagram */
if ((ipr->p == NULL) || (((struct ip_reass_helper*)ipr->p->payload)->start != 0)) {
valid = 0;
} else {
/* and check that there are no holes after this datagram */
iprh_prev = iprh;
q = iprh->next_pbuf;
while (q != NULL) {
iprh = (struct ip_reass_helper*)q->payload;
if (iprh_prev->end != iprh->start) {
valid = 0;
break;
}
iprh_prev = iprh;
q = iprh->next_pbuf;
}
/* if still valid, all fragments are received
* (because to the MF==0 already arrived */
if (valid) {
LWIP_ASSERT("sanity check", ipr->p != NULL);
LWIP_ASSERT("sanity check",
((struct ip_reass_helper*)ipr->p->payload) != iprh);
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
iprh->next_pbuf == NULL);
LWIP_ASSERT("validate_datagram:datagram end!=datagram len",
iprh->end == ipr->datagram_len);
}
}
}
/* If valid is 0 here, there are some fragments missing in the middle
* (since MF == 0 has already arrived). Such datagrams simply time out if
* no more fragments are received... */
return valid;
}
/* If we come here, not all fragments were received, yet! */
return 0; /* not yet valid! */
#if IP_REASS_CHECK_OVERLAP
freepbuf:
ip_reass_pbufcount -= pbuf_clen(new_p);
pbuf_free(new_p);
return 0;
#endif /* IP_REASS_CHECK_OVERLAP */
}
/**
* Reassembles incoming IP fragments into an IP datagram.
*
* @param p points to a pbuf chain of the fragment
* @return NULL if reassembly is incomplete, ? otherwise
*/
struct pbuf *
ip4_reass(struct pbuf *p)
{
struct pbuf *r;
struct ip_hdr *fraghdr;
struct ip_reassdata *ipr;
struct ip_reass_helper *iprh;
u16_t offset, len;
u8_t clen;
IPFRAG_STATS_INC(ip_frag.recv);
MIB2_STATS_INC(mib2.ipreasmreqds);
fraghdr = (struct ip_hdr*)p->payload;
if ((IPH_HL(fraghdr) * 4) != IP_HLEN) {
LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: IP options currently not supported!\n"));
IPFRAG_STATS_INC(ip_frag.err);
goto nullreturn;
}
offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
/* Check if we are allowed to enqueue more datagrams. */
clen = pbuf_clen(p);
if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
#if IP_REASS_FREE_OLDEST
if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
#endif /* IP_REASS_FREE_OLDEST */
{
/* No datagram could be freed and still too many pbufs enqueued */
LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n",
ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
IPFRAG_STATS_INC(ip_frag.memerr);
/* @todo: send ICMP time exceeded here? */
/* drop this pbuf */
goto nullreturn;
}
}
/* Look for the datagram the fragment belongs to in the current datagram queue,
* remembering the previous in the queue for later dequeueing. */
for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) {
/* Check if the incoming fragment matches the one currently present
in the reassembly buffer. If so, we proceed with copying the
fragment into the buffer. */
if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
ntohs(IPH_ID(fraghdr))));
IPFRAG_STATS_INC(ip_frag.cachehit);
break;
}
}
if (ipr == NULL) {
/* Enqueue a new datagram into the datagram queue */
ipr = ip_reass_enqueue_new_datagram(fraghdr, clen);
/* Bail if unable to enqueue */
if (ipr == NULL) {
goto nullreturn;
}
} else {
if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
/* ipr->iphdr is not the header from the first fragment, but fraghdr is
* -> copy fraghdr into ipr->iphdr since we want to have the header
* of the first fragment (for ICMP time exceeded and later, for copying
* all options, if supported)*/
SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN);
}
}
/* Track the current number of pbufs current 'in-flight', in order to limit
the number of fragments that may be enqueued at any one time */
ip_reass_pbufcount += clen;
/* At this point, we have either created a new entry or pointing
* to an existing one */
/* check for 'no more fragments', and update queue entry*/
if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) {
ipr->flags |= IP_REASS_FLAG_LASTFRAG;
ipr->datagram_len = offset + len;
LWIP_DEBUGF(IP_REASS_DEBUG,
("ip4_reass: last fragment seen, total len %"S16_F"\n",
ipr->datagram_len));
}
/* find the right place to insert this pbuf */
/* @todo: trim pbufs if fragments are overlapping */
if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) {
struct ip_reassdata *ipr_prev;
/* the totally last fragment (flag more fragments = 0) was received at least
* once AND all fragments are received */
ipr->datagram_len += IP_HLEN;
/* save the second pbuf before copying the header over the pointer */
r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf;
/* copy the original ip header back to the first pbuf */
fraghdr = (struct ip_hdr*)(ipr->p->payload);
SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
IPH_LEN_SET(fraghdr, htons(ipr->datagram_len));
IPH_OFFSET_SET(fraghdr, 0);
IPH_CHKSUM_SET(fraghdr, 0);
/* @todo: do we need to set/calculate the correct checksum? */
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */
p = ipr->p;
/* chain together the pbufs contained within the reass_data list. */
while (r != NULL) {
iprh = (struct ip_reass_helper*)r->payload;
/* hide the ip header for every succeeding fragment */
pbuf_header(r, -IP_HLEN);
pbuf_cat(p, r);
r = iprh->next_pbuf;
}
/* find the previous entry in the linked list */
if (ipr == reassdatagrams) {
ipr_prev = NULL;
} else {
for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
if (ipr_prev->next == ipr) {
break;
}
}
}
/* release the sources allocate for the fragment queue entry */
ip_reass_dequeue_datagram(ipr, ipr_prev);
/* and adjust the number of pbufs currently queued for reassembly. */
ip_reass_pbufcount -= pbuf_clen(p);
MIB2_STATS_INC(mib2.ipreasmoks);
/* Return the pbuf chain */
return p;
}
/* the datagram is not (yet?) reassembled completely */
LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount));
return NULL;
nullreturn:
LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: nullreturn\n"));
IPFRAG_STATS_INC(ip_frag.drop);
pbuf_free(p);
return NULL;
}
#endif /* IP_REASSEMBLY */
#if IP_FRAG
#if IP_FRAG_USES_STATIC_BUF
static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)];
#else /* IP_FRAG_USES_STATIC_BUF */
#if !LWIP_NETIF_TX_SINGLE_PBUF
/** Allocate a new struct pbuf_custom_ref */
static struct pbuf_custom_ref*
ip_frag_alloc_pbuf_custom_ref(void)
{
return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF);
}
/** Free a struct pbuf_custom_ref */
static void
ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
{
LWIP_ASSERT("p != NULL", p != NULL);
memp_free(MEMP_FRAG_PBUF, p);
}
/** Free-callback function to free a 'struct pbuf_custom_ref', called by
* pbuf_free. */
static void
ipfrag_free_pbuf_custom(struct pbuf *p)
{
struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p;
LWIP_ASSERT("pcr != NULL", pcr != NULL);
LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p);
if (pcr->original != NULL) {
pbuf_free(pcr->original);
}
ip_frag_free_pbuf_custom_ref(pcr);
}
#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
#endif /* IP_FRAG_USES_STATIC_BUF */
/**
* Fragment an IP datagram if too large for the netif.
*
* Chop the datagram in MTU sized chunks and send them in order
* by using a fixed size static memory buffer (PBUF_REF) or
* point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF).
*
* @param p ip packet to send
* @param netif the netif on which to send
* @param dest destination ip address to which to send
*
* @return ERR_OK if sent successfully, err_t otherwise
*/
err_t
ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
{
struct pbuf *rambuf;
#if IP_FRAG_USES_STATIC_BUF
struct pbuf *header;
#else
#if !LWIP_NETIF_TX_SINGLE_PBUF
struct pbuf *newpbuf;
#endif
struct ip_hdr *original_iphdr;
#endif
struct ip_hdr *iphdr;
u16_t nfb;
u16_t left, cop;
u16_t mtu = netif->mtu;
u16_t ofo, omf;
u16_t last;
u16_t poff = IP_HLEN;
u16_t tmp;
#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF
u16_t newpbuflen = 0;
u16_t left_to_copy;
#endif
/* Get a RAM based MTU sized pbuf */
#if IP_FRAG_USES_STATIC_BUF
/* When using a static buffer, we use a PBUF_REF, which we will
* use to reference the packet (without link header).
* Layer and length is irrelevant.
*/
rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF);
if (rambuf == NULL) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n"));
goto memerr;
}
rambuf->tot_len = rambuf->len = mtu;
rambuf->payload = LWIP_MEM_ALIGN((void *)buf);
/* Copy the IP header in it */
iphdr = (struct ip_hdr *)rambuf->payload;
SMEMCPY(iphdr, p->payload, IP_HLEN);
#else /* IP_FRAG_USES_STATIC_BUF */
original_iphdr = (struct ip_hdr *)p->payload;
iphdr = original_iphdr;
#endif /* IP_FRAG_USES_STATIC_BUF */
/* Save original offset */
tmp = ntohs(IPH_OFFSET(iphdr));
ofo = tmp & IP_OFFMASK;
omf = tmp & IP_MF;
left = p->tot_len - IP_HLEN;
nfb = (mtu - IP_HLEN) / 8;
while (left) {
last = (left <= mtu - IP_HLEN);
/* Set new offset and MF flag */
tmp = omf | (IP_OFFMASK & (ofo));
if (!last) {
tmp = tmp | IP_MF;
}
/* Fill this fragment */
cop = last ? left : nfb * 8;
#if IP_FRAG_USES_STATIC_BUF
poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff);
#else /* IP_FRAG_USES_STATIC_BUF */
#if LWIP_NETIF_TX_SINGLE_PBUF
rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM);
if (rambuf == NULL) {
goto memerr;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
poff += pbuf_copy_partial(p, rambuf->payload, cop, poff);
/* make room for the IP header */
if (pbuf_header(rambuf, IP_HLEN)) {
pbuf_free(rambuf);
goto memerr;
}
/* fill in the IP header */
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = (struct ip_hdr*)rambuf->payload;
#else /* LWIP_NETIF_TX_SINGLE_PBUF */
/* When not using a static buffer, create a chain of pbufs.
* The first will be a PBUF_RAM holding the link and IP header.
* The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
* but limited to the size of an mtu.
*/
rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM);
if (rambuf == NULL) {
goto memerr;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(p->len >= (IP_HLEN)));
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = (struct ip_hdr *)rambuf->payload;
/* Can just adjust p directly for needed offset. */
p->payload = (u8_t *)p->payload + poff;
p->len -= poff;
left_to_copy = cop;
while (left_to_copy) {
struct pbuf_custom_ref *pcr;
newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len;
/* Is this pbuf already empty? */
if (!newpbuflen) {
p = p->next;
continue;
}
pcr = ip_frag_alloc_pbuf_custom_ref();
if (pcr == NULL) {
pbuf_free(rambuf);
goto memerr;
}
/* Mirror this pbuf, although we might not need all of it. */
newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen);
if (newpbuf == NULL) {
ip_frag_free_pbuf_custom_ref(pcr);
pbuf_free(rambuf);
goto memerr;
}
pbuf_ref(p);
pcr->original = p;
pcr->pc.custom_free_function = ipfrag_free_pbuf_custom;
/* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
* so that it is removed when pbuf_dechain is later called on rambuf.
*/
pbuf_cat(rambuf, newpbuf);
left_to_copy -= newpbuflen;
if (left_to_copy) {
p = p->next;
}
}
poff = newpbuflen;
#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
#endif /* IP_FRAG_USES_STATIC_BUF */
/* Correct header */
IPH_OFFSET_SET(iphdr, htons(tmp));
IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */
#if IP_FRAG_USES_STATIC_BUF
if (last) {
pbuf_realloc(rambuf, left + IP_HLEN);
}
/* This part is ugly: we alloc a RAM based pbuf for
* the link level header for each chunk and then
* free it. A PBUF_ROM style pbuf for which pbuf_header
* worked would make things simpler.
*/
header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);
if (header != NULL) {
pbuf_chain(header, rambuf);
netif->output(netif, header, dest);
IPFRAG_STATS_INC(ip_frag.xmit);
MIB2_STATS_INC(mib2.ipfragcreates);
pbuf_free(header);
} else {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n"));
pbuf_free(rambuf);
goto memerr;
}
#else /* IP_FRAG_USES_STATIC_BUF */
/* No need for separate header pbuf - we allowed room for it in rambuf
* when allocated.
*/
netif->output(netif, rambuf, dest);
IPFRAG_STATS_INC(ip_frag.xmit);
/* Unfortunately we can't reuse rambuf - the hardware may still be
* using the buffer. Instead we free it (and the ensuing chain) and
* recreate it next time round the loop. If we're lucky the hardware
* will have already sent the packet, the free will really free, and
* there will be zero memory penalty.
*/
pbuf_free(rambuf);
#endif /* IP_FRAG_USES_STATIC_BUF */
left -= cop;
ofo += nfb;
}
#if IP_FRAG_USES_STATIC_BUF
pbuf_free(rambuf);
#endif /* IP_FRAG_USES_STATIC_BUF */
MIB2_STATS_INC(mib2.ipfragoks);
return ERR_OK;
memerr:
MIB2_STATS_INC(mib2.ipfragfails);
return ERR_MEM;
}
#endif /* IP_FRAG */
#endif /* LWIP_IPV4 */

View file

@ -1 +0,0 @@
IPv6 support in lwIP is very experimental.

View file

@ -1,50 +0,0 @@
/**
* @file
*
* DHCPv6.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#include "lwip/opt.h"
#if LWIP_IPV6 && LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/ip6_addr.h"
#include "lwip/def.h"
#endif /* LWIP_IPV6 && LWIP_IPV6_DHCP6 */

View file

@ -1,159 +0,0 @@
/**
* @file
*
* Ethernet output for IPv6. Uses ND tables for link-layer addressing.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#include "lwip/opt.h"
#if LWIP_IPV6 && LWIP_ETHERNET
#include "lwip/ethip6.h"
#include "lwip/nd6.h"
#include "lwip/pbuf.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/icmp6.h"
#include "netif/ethernet.h"
#include <string.h>
/**
* Send an IPv6 packet on the network using netif->linkoutput
* The ethernet header is filled in before sending.
*
* @params netif the lwIP network interface on which to send the packet
* @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header
* @params src the source MAC address to be copied into the ethernet header
* @params dst the destination MAC address to be copied into the ethernet header
* @return ERR_OK if the packet was sent, any other err_t on failure
*/
static err_t
ethip6_send(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst)
{
struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
LWIP_ASSERT("netif->hwaddr_len must be 6 for ethip6!",
(netif->hwaddr_len == 6));
SMEMCPY(&ethhdr->dest, dst, 6);
SMEMCPY(&ethhdr->src, src, 6);
ethhdr->type = PP_HTONS(ETHTYPE_IPV6);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethip6_send: sending packet %p\n", (void *)p));
/* send the packet */
return netif->linkoutput(netif, p);
}
/**
* Resolve and fill-in Ethernet address header for outgoing IPv6 packet.
*
* For IPv6 multicast, corresponding Ethernet addresses
* are selected and the packet is transmitted on the link.
*
* For unicast addresses, ...
*
* @TODO anycast addresses
*
* @param netif The lwIP network interface which the IP packet will be sent on.
* @param q The pbuf(s) containing the IP packet to be sent.
* @param ip6addr The IP address of the packet destination.
*
* @return
* - ERR_RTE No route to destination (no gateway to external networks),
* or the return type of either etharp_query() or etharp_send_ip().
*/
err_t
ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
{
struct eth_addr dest;
s8_t i;
/* make room for Ethernet header - should not fail */
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
/* bail out */
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("etharp_output: could not allocate room for header.\n"));
return ERR_BUF;
}
/* multicast destination IP address? */
if (ip6_addr_ismulticast(ip6addr)) {
/* Hash IP multicast address to MAC address.*/
dest.addr[0] = 0x33;
dest.addr[1] = 0x33;
dest.addr[2] = ((const u8_t *)(&(ip6addr->addr[3])))[0];
dest.addr[3] = ((const u8_t *)(&(ip6addr->addr[3])))[1];
dest.addr[4] = ((const u8_t *)(&(ip6addr->addr[3])))[2];
dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3];
/* Send out. */
return ethip6_send(netif, q, (struct eth_addr*)(netif->hwaddr), &dest);
}
/* We have a unicast destination IP address */
/* TODO anycast? */
/* Get next hop record. */
i = nd6_get_next_hop_entry(ip6addr, netif);
if (i < 0) {
/* failed to get a next hop neighbor record. */
return ERR_MEM;
}
/* Now that we have a destination record, send or queue the packet. */
if (neighbor_cache[i].state == ND6_STALE) {
/* Switch to delay state. */
neighbor_cache[i].state = ND6_DELAY;
neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME;
}
/* TODO should we send or queue if PROBE? send for now, to let unicast NS pass. */
if ((neighbor_cache[i].state == ND6_REACHABLE) ||
(neighbor_cache[i].state == ND6_DELAY) ||
(neighbor_cache[i].state == ND6_PROBE)) {
/* Send out. */
SMEMCPY(dest.addr, neighbor_cache[i].lladdr, 6);
return ethip6_send(netif, q, (struct eth_addr*)(netif->hwaddr), &dest);
}
/* We should queue packet on this interface. */
pbuf_header(q, -(s16_t)SIZEOF_ETH_HDR);
return nd6_queue_packet(i, q);
}
#endif /* LWIP_IPV6 && LWIP_ETHERNET */

View file

@ -1,349 +0,0 @@
/**
* @file
*
* IPv6 version of ICMP, as per RFC 4443.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#include "lwip/opt.h"
#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/icmp6.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#include "lwip/nd6.h"
#include "lwip/mld6.h"
#include "lwip/ip.h"
#include "lwip/stats.h"
#include <string.h>
#ifndef LWIP_ICMP6_DATASIZE
#define LWIP_ICMP6_DATASIZE 8
#endif
#if LWIP_ICMP6_DATASIZE == 0
#define LWIP_ICMP6_DATASIZE 8
#endif
/* Forward declarations */
static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type);
/**
* Process an input ICMPv6 message. Called by ip6_input.
*
* Will generate a reply for echo requests. Other messages are forwarded
* to nd6_input, or mld6_input.
*
* @param p the mld packet, p->payload pointing to the icmpv6 header
* @param inp the netif on which this packet was received
*/
void
icmp6_input(struct pbuf *p, struct netif *inp)
{
struct icmp6_hdr *icmp6hdr;
struct pbuf * r;
const ip6_addr_t * reply_src;
ICMP6_STATS_INC(icmp6.recv);
/* Check that ICMPv6 header fits in payload */
if (p->len < sizeof(struct icmp6_hdr)) {
/* drop short packets */
pbuf_free(p);
ICMP6_STATS_INC(icmp6.lenerr);
ICMP6_STATS_INC(icmp6.drop);
return;
}
icmp6hdr = (struct icmp6_hdr *)p->payload;
#if CHECKSUM_CHECK_ICMP6
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) {
if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(),
ip6_current_dest_addr()) != 0) {
/* Checksum failed */
pbuf_free(p);
ICMP6_STATS_INC(icmp6.chkerr);
ICMP6_STATS_INC(icmp6.drop);
return;
}
}
#endif /* CHECKSUM_CHECK_ICMP6 */
switch (icmp6hdr->type) {
case ICMP6_TYPE_NA: /* Neighbor advertisement */
case ICMP6_TYPE_NS: /* Neighbor solicitation */
case ICMP6_TYPE_RA: /* Router advertisement */
case ICMP6_TYPE_RD: /* Redirect */
case ICMP6_TYPE_PTB: /* Packet too big */
nd6_input(p, inp);
return;
break;
case ICMP6_TYPE_RS:
#if LWIP_IPV6_FORWARD
/* TODO implement router functionality */
#endif
break;
#if LWIP_IPV6_MLD
case ICMP6_TYPE_MLQ:
case ICMP6_TYPE_MLR:
case ICMP6_TYPE_MLD:
mld6_input(p, inp);
return;
break;
#endif
case ICMP6_TYPE_EREQ:
#if !LWIP_MULTICAST_PING
/* multicast destination address? */
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
/* drop */
pbuf_free(p);
ICMP6_STATS_INC(icmp6.drop);
return;
}
#endif /* LWIP_MULTICAST_PING */
/* Allocate reply. */
r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM);
if (r == NULL) {
/* drop */
pbuf_free(p);
ICMP6_STATS_INC(icmp6.memerr);
return;
}
/* Copy echo request. */
if (pbuf_copy(r, p) != ERR_OK) {
/* drop */
pbuf_free(p);
pbuf_free(r);
ICMP6_STATS_INC(icmp6.err);
return;
}
/* Determine reply source IPv6 address. */
#if LWIP_MULTICAST_PING
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr()));
if (reply_src == NULL) {
/* drop */
pbuf_free(p);
pbuf_free(r);
ICMP6_STATS_INC(icmp6.rterr);
return;
}
}
else
#endif /* LWIP_MULTICAST_PING */
{
reply_src = ip6_current_dest_addr();
}
/* Set fields in reply. */
((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP;
((struct icmp6_echo_hdr *)(r->payload))->chksum = 0;
#if CHECKSUM_GEN_ICMP6
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) {
((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r,
IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr());
}
#endif /* CHECKSUM_GEN_ICMP6 */
/* Send reply. */
ICMP6_STATS_INC(icmp6.xmit);
ip6_output_if(r, reply_src, ip6_current_src_addr(),
LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp);
pbuf_free(r);
break;
default:
ICMP6_STATS_INC(icmp6.proterr);
ICMP6_STATS_INC(icmp6.drop);
break;
}
pbuf_free(p);
}
/**
* Send an icmpv6 'destination unreachable' packet.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IPv6 header
* @param c ICMPv6 code for the unreachable type
*/
void
icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c)
{
icmp6_send_response(p, c, 0, ICMP6_TYPE_DUR);
}
/**
* Send an icmpv6 'packet too big' packet.
*
* @param p the input packet for which the 'packet too big' should be sent,
* p->payload pointing to the IPv6 header
* @param mtu the maximum mtu that we can accept
*/
void
icmp6_packet_too_big(struct pbuf *p, u32_t mtu)
{
icmp6_send_response(p, 0, mtu, ICMP6_TYPE_PTB);
}
/**
* Send an icmpv6 'time exceeded' packet.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IPv6 header
* @param c ICMPv6 code for the time exceeded type
*/
void
icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c)
{
icmp6_send_response(p, c, 0, ICMP6_TYPE_TE);
}
/**
* Send an icmpv6 'parameter problem' packet.
*
* @param p the input packet for which the 'param problem' should be sent,
* p->payload pointing to the IP header
* @param c ICMPv6 code for the param problem type
* @param pointer the pointer to the byte where the parameter is found
*/
void
icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer)
{
icmp6_send_response(p, c, pointer, ICMP6_TYPE_PP);
}
/**
* Send an ICMPv6 packet in response to an incoming packet.
*
* @param p the input packet for which the response should be sent,
* p->payload pointing to the IPv6 header
* @param code Code of the ICMPv6 header
* @param data Additional 32-bit parameter in the ICMPv6 header
* @param type Type of the ICMPv6 header
*/
static void
icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
{
struct pbuf *q;
struct icmp6_hdr *icmp6hdr;
const ip6_addr_t *reply_src;
ip6_addr_t *reply_dest;
ip6_addr_t reply_src_local, reply_dest_local;
struct ip6_hdr *ip6hdr;
struct netif *netif;
/* ICMPv6 header + IPv6 header + data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
PBUF_RAM);
if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
ICMP6_STATS_INC(icmp6.memerr);
return;
}
LWIP_ASSERT("check that first pbuf can hold icmp 6message",
(q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
icmp6hdr = (struct icmp6_hdr *)q->payload;
icmp6hdr->type = type;
icmp6hdr->code = code;
icmp6hdr->data = data;
/* copy fields from original packet */
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
IP6_HLEN + LWIP_ICMP6_DATASIZE);
/* Get the destination address and netif for this ICMP message. */
if ((ip_current_netif() == NULL) ||
((code == ICMP6_TE_FRAG) && (type == ICMP6_TYPE_TE))) {
/* Special case, as ip6_current_xxx is either NULL, or points
* to a different packet than the one that expired.
* We must use the addresses that are stored in the expired packet. */
ip6hdr = (struct ip6_hdr *)p->payload;
/* copy from packed address to aligned address */
ip6_addr_copy(reply_dest_local, ip6hdr->src);
ip6_addr_copy(reply_src_local, ip6hdr->dest);
reply_dest = &reply_dest_local;
reply_src = &reply_src_local;
netif = ip6_route(reply_src, reply_dest);
if (netif == NULL) {
/* drop */
pbuf_free(q);
ICMP6_STATS_INC(icmp6.rterr);
return;
}
}
else {
netif = ip_current_netif();
reply_dest = ip6_current_src_addr();
/* Select an address to use as source. */
reply_src = ip_2_ip6(ip6_select_source_address(netif, reply_dest));
if (reply_src == NULL) {
/* drop */
pbuf_free(q);
ICMP6_STATS_INC(icmp6.rterr);
return;
}
}
/* calculate checksum */
icmp6hdr->chksum = 0;
#if CHECKSUM_GEN_ICMP6
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len,
reply_src, reply_dest);
}
#endif /* CHECKSUM_GEN_ICMP6 */
ICMP6_STATS_INC(icmp6.xmit);
ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif);
pbuf_free(q);
}
#endif /* LWIP_ICMP6 && LWIP_IPV6 */

View file

@ -1,53 +0,0 @@
/**
* @file
*
* INET v6 addresses.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#include "lwip/opt.h"
#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/inet.h"
/** This variable is initialized by the system to contain the wildcard IPv6 address.
*/
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#endif /* LWIP_IPV6 */

File diff suppressed because it is too large Load diff

View file

@ -1,292 +0,0 @@
/**
* @file
*
* IPv6 addresses.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
* Functions for handling IPv6 addresses.
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#include "lwip/opt.h"
#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/ip_addr.h"
#include "lwip/def.h"
/* used by IP6_ADDR_ANY(6) in ip6_addr.h */
const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul);
#ifndef isprint
#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up)
#define isprint(c) in_range(c, 0x20, 0x7f)
#define isdigit(c) in_range(c, '0', '9')
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
#define islower(c) in_range(c, 'a', 'z')
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
#define xchar(i) ((i) < 10 ? '0' + (i) : 'A' + (i) - 10)
#endif
/**
* Check whether "cp" is a valid ascii representation
* of an IPv6 address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
*
* @param cp IPv6 address in ascii representation (e.g. "FF01::1")
* @param addr pointer to which to save the ip address in network order
* @return 1 if cp could be converted to addr, 0 on failure
*/
int
ip6addr_aton(const char *cp, ip6_addr_t *addr)
{
u32_t addr_index, zero_blocks, current_block_index, current_block_value;
const char * s;
/* Count the number of colons, to count the number of blocks in a "::" sequence
zero_blocks may be 1 even if there are no :: sequences */
zero_blocks = 8;
for (s = cp; *s != 0; s++) {
if (*s == ':') {
zero_blocks--;
} else if (!isxdigit(*s)) {
break;
}
}
/* parse each block */
addr_index = 0;
current_block_index = 0;
current_block_value = 0;
for (s = cp; *s != 0; s++) {
if (*s == ':') {
if (addr) {
if (current_block_index & 0x1) {
addr->addr[addr_index++] |= current_block_value;
}
else {
addr->addr[addr_index] = current_block_value << 16;
}
}
current_block_index++;
current_block_value = 0;
if (current_block_index > 7) {
/* address too long! */
return 0;
}
if (s[1] == ':') {
if (s[2] == ':') {
/* invalid format: three successive colons */
return 0;
}
s++;
/* "::" found, set zeros */
while (zero_blocks > 0) {
zero_blocks--;
if (current_block_index & 0x1) {
addr_index++;
} else {
if (addr) {
addr->addr[addr_index] = 0;
}
}
current_block_index++;
if (current_block_index > 7) {
/* address too long! */
return 0;
}
}
}
} else if (isxdigit(*s)) {
/* add current digit */
current_block_value = (current_block_value << 4) +
(isdigit(*s) ? *s - '0' :
10 + (islower(*s) ? *s - 'a' : *s - 'A'));
} else {
/* unexpected digit, space? CRLF? */
break;
}
}
if (addr) {
if (current_block_index & 0x1) {
addr->addr[addr_index++] |= current_block_value;
}
else {
addr->addr[addr_index] = current_block_value << 16;
}
}
/* convert to network byte order. */
if (addr) {
for (addr_index = 0; addr_index < 4; addr_index++) {
addr->addr[addr_index] = htonl(addr->addr[addr_index]);
}
}
if (current_block_index != 7) {
return 0;
}
return 1;
}
/**
* Convert numeric IPv6 address into ASCII representation.
* returns ptr to static buffer; not reentrant!
*
* @param addr ip6 address in network order to convert
* @return pointer to a global static (!) buffer that holds the ASCII
* representation of addr
*/
char *
ip6addr_ntoa(const ip6_addr_t *addr)
{
static char str[40];
return ip6addr_ntoa_r(addr, str, 40);
}
/**
* Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
*
* @param addr ip6 address in network order to convert
* @param buf target buffer where the string is stored
* @param buflen length of buf
* @return either pointer to buf which now holds the ASCII
* representation of addr or NULL if buf was too small
*/
char *
ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
{
u32_t current_block_index, current_block_value, next_block_value;
s32_t i;
u8_t zero_flag, empty_block_flag;
i = 0;
empty_block_flag = 0; /* used to indicate a zero chain for "::' */
for (current_block_index = 0; current_block_index < 8; current_block_index++) {
/* get the current 16-bit block */
current_block_value = htonl(addr->addr[current_block_index >> 1]);
if ((current_block_index & 0x1) == 0) {
current_block_value = current_block_value >> 16;
}
current_block_value &= 0xffff;
/* Check for empty block. */
if (current_block_value == 0) {
if (current_block_index == 7) {
/* special case, we must render a ':' for the last block. */
buf[i++] = ':';
if (i >= buflen) {
return NULL;
}
break;
}
if (empty_block_flag == 0) {
/* generate empty block "::", but only if more than one contiguous zero block,
* according to current formatting suggestions RFC 5952. */
next_block_value = htonl(addr->addr[(current_block_index + 1) >> 1]);
if ((current_block_index & 0x1) == 0x01) {
next_block_value = next_block_value >> 16;
}
next_block_value &= 0xffff;
if (next_block_value == 0) {
empty_block_flag = 1;
buf[i++] = ':';
if (i >= buflen) {
return NULL;
}
continue; /* move on to next block. */
}
} else if (empty_block_flag == 1) {
/* move on to next block. */
continue;
}
} else if (empty_block_flag == 1) {
/* Set this flag value so we don't produce multiple empty blocks. */
empty_block_flag = 2;
}
if (current_block_index > 0) {
buf[i++] = ':';
if (i >= buflen) {
return NULL;
}
}
if ((current_block_value & 0xf000) == 0) {
zero_flag = 1;
} else {
buf[i++] = xchar(((current_block_value & 0xf000) >> 12));
zero_flag = 0;
if (i >= buflen) {
return NULL;
}
}
if (((current_block_value & 0xf00) == 0) && (zero_flag)) {
/* do nothing */
} else {
buf[i++] = xchar(((current_block_value & 0xf00) >> 8));
zero_flag = 0;
if (i >= buflen) {
return NULL;
}
}
if (((current_block_value & 0xf0) == 0) && (zero_flag)) {
/* do nothing */
}
else {
buf[i++] = xchar(((current_block_value & 0xf0) >> 4));
zero_flag = 0;
if (i >= buflen) {
return NULL;
}
}
buf[i++] = xchar((current_block_value & 0xf));
if (i >= buflen) {
return NULL;
}
}
buf[i] = 0;
return buf;
}
#endif /* LWIP_IPV6 */

View file

@ -1,773 +0,0 @@
/**
* @file
*
* IPv6 fragmentation and reassembly.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#include "lwip/opt.h"
#include "lwip/ip6_frag.h"
#include "lwip/ip6.h"
#include "lwip/icmp6.h"
#include "lwip/nd6.h"
#include "lwip/ip.h"
#include "lwip/pbuf.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include <string.h>
#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */
/** Setting this to 0, you can turn off checking the fragments for overlapping
* regions. The code gets a little smaller. Only use this if you know that
* overlapping won't occur on your network! */
#ifndef IP_REASS_CHECK_OVERLAP
#define IP_REASS_CHECK_OVERLAP 1
#endif /* IP_REASS_CHECK_OVERLAP */
/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is
* full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller.
* Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA
* is set to 1, so one datagram can be reassembled at a time, only. */
#ifndef IP_REASS_FREE_OLDEST
#define IP_REASS_FREE_OLDEST 1
#endif /* IP_REASS_FREE_OLDEST */
#if IPV6_FRAG_COPYHEADER
#define IPV6_FRAG_REQROOM ((s16_t)(sizeof(struct ip6_reass_helper) - IP6_FRAG_HLEN))
#endif
#define IP_REASS_FLAG_LASTFRAG 0x01
/** This is a helper struct which holds the starting
* offset and the ending offset of this fragment to
* easily chain the fragments.
* It has the same packing requirements as the IPv6 header, since it replaces
* the Fragment Header in memory in incoming fragments to keep
* track of the various fragments.
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip6_reass_helper {
PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
PACK_STRUCT_FIELD(u16_t start);
PACK_STRUCT_FIELD(u16_t end);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/* static variables */
static struct ip6_reassdata *reassdatagrams;
static u16_t ip6_reass_pbufcount;
/* Forward declarations. */
static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr);
#if IP_REASS_FREE_OLDEST
static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed);
#endif /* IP_REASS_FREE_OLDEST */
void
ip6_reass_tmr(void)
{
struct ip6_reassdata *r, *tmp;
#if !IPV6_FRAG_COPYHEADER
LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
#endif /* !IPV6_FRAG_COPYHEADER */
r = reassdatagrams;
while (r != NULL) {
/* Decrement the timer. Once it reaches 0,
* clean up the incomplete fragment assembly */
if (r->timer > 0) {
r->timer--;
r = r->next;
} else {
/* reassembly timed out */
tmp = r;
/* get the next pointer before freeing */
r = r->next;
/* free the helper struct and all enqueued pbufs */
ip6_reass_free_complete_datagram(tmp);
}
}
}
/**
* Free a datagram (struct ip6_reassdata) and all its pbufs.
* Updates the total count of enqueued pbufs (ip6_reass_pbufcount),
* sends an ICMP time exceeded packet.
*
* @param ipr datagram to free
*/
static void
ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
{
struct ip6_reassdata *prev;
u16_t pbufs_freed = 0;
u8_t clen;
struct pbuf *p;
struct ip6_reass_helper *iprh;
#if LWIP_ICMP6
iprh = (struct ip6_reass_helper *)ipr->p->payload;
if (iprh->start == 0) {
/* The first fragment was received, send ICMP time exceeded. */
/* First, de-queue the first pbuf from r->p. */
p = ipr->p;
ipr->p = iprh->next_pbuf;
/* Then, move back to the original ipv6 header (we are now pointing to Fragment header).
This cannot fail since we already checked when receiving this fragment. */
if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)IPV6_FRAG_HDRREF(ipr->iphdr)))) {
LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0);
}
else {
icmp6_time_exceeded(p, ICMP6_TE_FRAG);
}
clen = pbuf_clen(p);
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
pbufs_freed += clen;
pbuf_free(p);
}
#endif /* LWIP_ICMP6 */
/* First, free all received pbufs. The individual pbufs need to be released
separately as they have not yet been chained */
p = ipr->p;
while (p != NULL) {
struct pbuf *pcur;
iprh = (struct ip6_reass_helper *)p->payload;
pcur = p;
/* get the next pointer before freeing */
p = iprh->next_pbuf;
clen = pbuf_clen(pcur);
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
pbufs_freed += clen;
pbuf_free(pcur);
}
/* Then, unchain the struct ip6_reassdata from the list and free it. */
if (ipr == reassdatagrams) {
reassdatagrams = ipr->next;
} else {
prev = reassdatagrams;
while (prev != NULL) {
if (prev->next == ipr) {
break;
}
prev = prev->next;
}
if (prev != NULL) {
prev->next = ipr->next;
}
}
memp_free(MEMP_IP6_REASSDATA, ipr);
/* Finally, update number of pbufs in reassembly queue */
LWIP_ASSERT("ip_reass_pbufcount >= clen", ip6_reass_pbufcount >= pbufs_freed);
ip6_reass_pbufcount -= pbufs_freed;
}
#if IP_REASS_FREE_OLDEST
/**
* Free the oldest datagram to make room for enqueueing new fragments.
* The datagram ipr is not freed!
*
* @param ipr ip6_reassdata for the current fragment
* @param pbufs_needed number of pbufs needed to enqueue
* (used for freeing other datagrams if not enough space)
*/
static void
ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed)
{
struct ip6_reassdata *r, *oldest;
/* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs,
* but don't free the current datagram! */
do {
r = oldest = reassdatagrams;
while (r != NULL) {
if (r != ipr) {
if (r->timer <= oldest->timer) {
/* older than the previous oldest */
oldest = r;
}
}
r = r->next;
}
if (oldest == ipr) {
/* nothing to free, ipr is the only element on the list */
return;
}
if (oldest != NULL) {
ip6_reass_free_complete_datagram(oldest);
}
} while (((ip6_reass_pbufcount + pbufs_needed) > IP_REASS_MAX_PBUFS) && (reassdatagrams != NULL));
}
#endif /* IP_REASS_FREE_OLDEST */
/**
* Reassembles incoming IPv6 fragments into an IPv6 datagram.
*
* @param p points to the IPv6 Fragment Header
* @param len the length of the payload (after Fragment Header)
* @return NULL if reassembly is incomplete, pbuf pointing to
* IPv6 Header if reassembly is complete
*/
struct pbuf *
ip6_reass(struct pbuf *p)
{
struct ip6_reassdata *ipr, *ipr_prev;
struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
struct ip6_frag_hdr * frag_hdr;
u16_t offset, len;
u8_t clen, valid = 1;
struct pbuf *q;
IP6_FRAG_STATS_INC(ip6_frag.recv);
LWIP_ASSERT("ip6_frag_hdr must be in the first pbuf, not chained",
(const void*)ip6_current_header() == ((u8_t*)p->payload) - IP6_HLEN);
frag_hdr = (struct ip6_frag_hdr *) p->payload;
clen = pbuf_clen(p);
offset = ntohs(frag_hdr->_fragment_offset);
/* Calculate fragment length from IPv6 payload length.
* Adjust for headers before Fragment Header.
* And finally adjust by Fragment Header length. */
len = ntohs(ip6_current_header()->_plen);
len -= (u16_t)(((u8_t*)p->payload - (const u8_t*)ip6_current_header()) - IP6_HLEN);
len -= IP6_FRAG_HLEN;
/* Look for the datagram the fragment belongs to in the current datagram queue,
* remembering the previous in the queue for later dequeueing. */
for (ipr = reassdatagrams, ipr_prev = NULL; ipr != NULL; ipr = ipr->next) {
/* Check if the incoming fragment matches the one currently present
in the reassembly buffer. If so, we proceed with copying the
fragment into the buffer. */
if ((frag_hdr->_identification == ipr->identification) &&
ip6_addr_cmp(ip6_current_src_addr(), &(IPV6_FRAG_HDRREF(ipr->iphdr)->src)) &&
ip6_addr_cmp(ip6_current_dest_addr(), &(IPV6_FRAG_HDRREF(ipr->iphdr)->dest))) {
IP6_FRAG_STATS_INC(ip6_frag.cachehit);
break;
}
ipr_prev = ipr;
}
if (ipr == NULL) {
/* Enqueue a new datagram into the datagram queue */
ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA);
if (ipr == NULL) {
#if IP_REASS_FREE_OLDEST
/* Make room and try again. */
ip6_reass_remove_oldest_datagram(ipr, clen);
ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA);
if (ipr != NULL) {
/* re-search ipr_prev since it might have been removed */
for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
if (ipr_prev->next == ipr) {
break;
}
}
} else
#endif /* IP_REASS_FREE_OLDEST */
{
IP6_FRAG_STATS_INC(ip6_frag.memerr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
}
}
memset(ipr, 0, sizeof(struct ip6_reassdata));
ipr->timer = IP_REASS_MAXAGE;
/* enqueue the new structure to the front of the list */
ipr->next = reassdatagrams;
reassdatagrams = ipr;
/* Use the current IPv6 header for src/dest address reference.
* Eventually, we will replace it when we get the first fragment
* (it might be this one, in any case, it is done later). */
#if IPV6_FRAG_COPYHEADER
MEMCPY(&ipr->iphdr, ip6_current_header(), IP6_HLEN);
#else /* IPV6_FRAG_COPYHEADER */
/* need to use the none-const pointer here: */
ipr->iphdr = ip_data.current_ip6_header;
#endif /* IPV6_FRAG_COPYHEADER */
/* copy the fragmented packet id. */
ipr->identification = frag_hdr->_identification;
/* copy the nexth field */
ipr->nexth = frag_hdr->_nexth;
}
/* Check if we are allowed to enqueue more datagrams. */
if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
#if IP_REASS_FREE_OLDEST
ip6_reass_remove_oldest_datagram(ipr, clen);
if ((ip6_reass_pbufcount + clen) <= IP_REASS_MAX_PBUFS) {
/* re-search ipr_prev since it might have been removed */
for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
if (ipr_prev->next == ipr) {
break;
}
}
} else
#endif /* IP_REASS_FREE_OLDEST */
{
/* @todo: send ICMPv6 time exceeded here? */
/* drop this pbuf */
IP6_FRAG_STATS_INC(ip6_frag.memerr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
}
}
/* Overwrite Fragment Header with our own helper struct. */
#if IPV6_FRAG_COPYHEADER
if (IPV6_FRAG_REQROOM > 0) {
/* Make room for struct ip6_reass_helper (only required if sizeof(void*) > 4).
This cannot fail since we already checked when receiving this fragment. */
err_t hdrerr = pbuf_header_force(p, IPV6_FRAG_REQROOM);
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == ERR_OK);
}
#else /* IPV6_FRAG_COPYHEADER */
LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
#endif /* IPV6_FRAG_COPYHEADER */
iprh = (struct ip6_reass_helper *)p->payload;
iprh->next_pbuf = NULL;
iprh->start = (offset & IP6_FRAG_OFFSET_MASK);
iprh->end = (offset & IP6_FRAG_OFFSET_MASK) + len;
/* find the right place to insert this pbuf */
/* Iterate through until we either get to the end of the list (append),
* or we find on with a larger offset (insert). */
for (q = ipr->p; q != NULL;) {
iprh_tmp = (struct ip6_reass_helper*)q->payload;
if (iprh->start < iprh_tmp->start) {
#if IP_REASS_CHECK_OVERLAP
if (iprh->end > iprh_tmp->start) {
/* fragment overlaps with following, throw away */
IP6_FRAG_STATS_INC(ip6_frag.proterr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
}
if (iprh_prev != NULL) {
if (iprh->start < iprh_prev->end) {
/* fragment overlaps with previous, throw away */
IP6_FRAG_STATS_INC(ip6_frag.proterr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
}
}
#endif /* IP_REASS_CHECK_OVERLAP */
/* the new pbuf should be inserted before this */
iprh->next_pbuf = q;
if (iprh_prev != NULL) {
/* not the fragment with the lowest offset */
iprh_prev->next_pbuf = p;
} else {
/* fragment with the lowest offset */
ipr->p = p;
}
break;
} else if (iprh->start == iprh_tmp->start) {
/* received the same datagram twice: no need to keep the datagram */
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
#if IP_REASS_CHECK_OVERLAP
} else if (iprh->start < iprh_tmp->end) {
/* overlap: no need to keep the new datagram */
IP6_FRAG_STATS_INC(ip6_frag.proterr);
IP6_FRAG_STATS_INC(ip6_frag.drop);
goto nullreturn;
#endif /* IP_REASS_CHECK_OVERLAP */
} else {
/* Check if the fragments received so far have no gaps. */
if (iprh_prev != NULL) {
if (iprh_prev->end != iprh_tmp->start) {
/* There is a fragment missing between the current
* and the previous fragment */
valid = 0;
}
}
}
q = iprh_tmp->next_pbuf;
iprh_prev = iprh_tmp;
}
/* If q is NULL, then we made it to the end of the list. Determine what to do now */
if (q == NULL) {
if (iprh_prev != NULL) {
/* this is (for now), the fragment with the highest offset:
* chain it to the last fragment */
#if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start);
#endif /* IP_REASS_CHECK_OVERLAP */
iprh_prev->next_pbuf = p;
if (iprh_prev->end != iprh->start) {
valid = 0;
}
} else {
#if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("no previous fragment, this must be the first fragment!",
ipr->p == NULL);
#endif /* IP_REASS_CHECK_OVERLAP */
/* this is the first fragment we ever received for this ip datagram */
ipr->p = p;
}
}
/* Track the current number of pbufs current 'in-flight', in order to limit
the number of fragments that may be enqueued at any one time */
ip6_reass_pbufcount += clen;
/* Remember IPv6 header if this is the first fragment. */
if (iprh->start == 0) {
#if IPV6_FRAG_COPYHEADER
if (iprh->next_pbuf != NULL) {
MEMCPY(&ipr->iphdr, ip6_current_header(), IP6_HLEN);
}
#else /* IPV6_FRAG_COPYHEADER */
/* need to use the none-const pointer here: */
ipr->iphdr = ip_data.current_ip6_header;
#endif /* IPV6_FRAG_COPYHEADER */
}
/* If this is the last fragment, calculate total packet length. */
if ((offset & IP6_FRAG_MORE_FLAG) == 0) {
ipr->datagram_len = iprh->end;
}
/* Additional validity tests: we have received first and last fragment. */
iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload;
if (iprh_tmp->start != 0) {
valid = 0;
}
if (ipr->datagram_len == 0) {
valid = 0;
}
/* Final validity test: no gaps between current and last fragment. */
iprh_prev = iprh;
q = iprh->next_pbuf;
while ((q != NULL) && valid) {
iprh = (struct ip6_reass_helper*)q->payload;
if (iprh_prev->end != iprh->start) {
valid = 0;
break;
}
iprh_prev = iprh;
q = iprh->next_pbuf;
}
if (valid) {
/* All fragments have been received */
struct ip6_hdr* iphdr_ptr;
/* chain together the pbufs contained within the ip6_reassdata list. */
iprh = (struct ip6_reass_helper*) ipr->p->payload;
while (iprh != NULL) {
struct pbuf* next_pbuf = iprh->next_pbuf;
if (next_pbuf != NULL) {
/* Save next helper struct (will be hidden in next step). */
iprh_tmp = (struct ip6_reass_helper*)next_pbuf->payload;
/* hide the fragment header for every succeeding fragment */
pbuf_header(next_pbuf, -IP6_FRAG_HLEN);
#if IPV6_FRAG_COPYHEADER
if (IPV6_FRAG_REQROOM > 0) {
/* hide the extra bytes borrowed from ip6_hdr for struct ip6_reass_helper */
err_t hdrerr = pbuf_header(next_pbuf, -(s16_t)(IPV6_FRAG_REQROOM));
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == ERR_OK);
}
#endif
pbuf_cat(ipr->p, next_pbuf);
}
else {
iprh_tmp = NULL;
}
iprh = iprh_tmp;
}
#if IPV6_FRAG_COPYHEADER
if (IPV6_FRAG_REQROOM > 0) {
/* get back room for struct ip6_reass_helper (only required if sizeof(void*) > 4) */
err_t hdrerr = pbuf_header(ipr->p, -(s16_t)(IPV6_FRAG_REQROOM));
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == ERR_OK);
}
iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->p->payload - IP6_HLEN);
MEMCPY(iphdr_ptr, &ipr->iphdr, IP6_HLEN);
#else
iphdr_ptr = ipr->iphdr;
#endif
/* Adjust datagram length by adding header lengths. */
ipr->datagram_len += (u16_t)(((u8_t*)ipr->p->payload - (u8_t*)iphdr_ptr)
+ IP6_FRAG_HLEN
- IP6_HLEN);
/* Set payload length in ip header. */
iphdr_ptr->_plen = htons(ipr->datagram_len);
/* Get the first pbuf. */
p = ipr->p;
/* Restore Fragment Header in first pbuf. Mark as "single fragment"
* packet. Restore nexth. */
frag_hdr = (struct ip6_frag_hdr *) p->payload;
frag_hdr->_nexth = ipr->nexth;
frag_hdr->reserved = 0;
frag_hdr->_fragment_offset = 0;
frag_hdr->_identification = 0;
/* release the sources allocate for the fragment queue entry */
if (reassdatagrams == ipr) {
/* it was the first in the list */
reassdatagrams = ipr->next;
} else {
/* it wasn't the first, so it must have a valid 'prev' */
LWIP_ASSERT("sanity check linked list", ipr_prev != NULL);
ipr_prev->next = ipr->next;
}
memp_free(MEMP_IP6_REASSDATA, ipr);
/* adjust the number of pbufs currently queued for reassembly. */
ip6_reass_pbufcount -= pbuf_clen(p);
/* Move pbuf back to IPv6 header.
This cannot fail since we already checked when receiving this fragment. */
if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)iphdr_ptr))) {
LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0);
pbuf_free(p);
return NULL;
}
/* Return the pbuf chain */
return p;
}
/* the datagram is not (yet?) reassembled completely */
return NULL;
nullreturn:
pbuf_free(p);
return NULL;
}
#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */
#if LWIP_IPV6 && LWIP_IPV6_FRAG
/** Allocate a new struct pbuf_custom_ref */
static struct pbuf_custom_ref*
ip6_frag_alloc_pbuf_custom_ref(void)
{
return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF);
}
/** Free a struct pbuf_custom_ref */
static void
ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
{
LWIP_ASSERT("p != NULL", p != NULL);
memp_free(MEMP_FRAG_PBUF, p);
}
/** Free-callback function to free a 'struct pbuf_custom_ref', called by
* pbuf_free. */
static void
ip6_frag_free_pbuf_custom(struct pbuf *p)
{
struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p;
LWIP_ASSERT("pcr != NULL", pcr != NULL);
LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p);
if (pcr->original != NULL) {
pbuf_free(pcr->original);
}
ip6_frag_free_pbuf_custom_ref(pcr);
}
/**
* Fragment an IPv6 datagram if too large for the netif or path MTU.
*
* Chop the datagram in MTU sized chunks and send them in order
* by pointing PBUF_REFs into p
*
* @param p ipv6 packet to send
* @param netif the netif on which to send
* @param dest destination ipv6 address to which to send
*
* @return ERR_OK if sent successfully, err_t otherwise
*/
err_t
ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
{
struct ip6_hdr *original_ip6hdr;
struct ip6_hdr *ip6hdr;
struct ip6_frag_hdr * frag_hdr;
struct pbuf *rambuf;
struct pbuf *newpbuf;
static u32_t identification;
u16_t nfb;
u16_t left, cop;
u16_t mtu;
u16_t fragment_offset = 0;
u16_t last;
u16_t poff = IP6_HLEN;
u16_t newpbuflen = 0;
u16_t left_to_copy;
identification++;
original_ip6hdr = (struct ip6_hdr *)p->payload;
mtu = nd6_get_destination_mtu(dest, netif);
/* TODO we assume there are no options in the unfragmentable part (IPv6 header). */
left = p->tot_len - IP6_HLEN;
nfb = (mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK;
while (left) {
last = (left <= nfb);
/* Fill this fragment */
cop = last ? left : nfb;
/* When not using a static buffer, create a chain of pbufs.
* The first will be a PBUF_RAM holding the link, IPv6, and Fragment header.
* The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
* but limited to the size of an mtu.
*/
rambuf = pbuf_alloc(PBUF_LINK, IP6_HLEN + IP6_FRAG_HLEN, PBUF_RAM);
if (rambuf == NULL) {
IP6_FRAG_STATS_INC(ip6_frag.memerr);
return ERR_MEM;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(p->len >= (IP6_HLEN + IP6_FRAG_HLEN)));
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
ip6hdr = (struct ip6_hdr *)rambuf->payload;
frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
/* Can just adjust p directly for needed offset. */
p->payload = (u8_t *)p->payload + poff;
p->len -= poff;
p->tot_len -= poff;
left_to_copy = cop;
while (left_to_copy) {
struct pbuf_custom_ref *pcr;
newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len;
/* Is this pbuf already empty? */
if (!newpbuflen) {
p = p->next;
continue;
}
pcr = ip6_frag_alloc_pbuf_custom_ref();
if (pcr == NULL) {
pbuf_free(rambuf);
IP6_FRAG_STATS_INC(ip6_frag.memerr);
return ERR_MEM;
}
/* Mirror this pbuf, although we might not need all of it. */
newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen);
if (newpbuf == NULL) {
ip6_frag_free_pbuf_custom_ref(pcr);
pbuf_free(rambuf);
IP6_FRAG_STATS_INC(ip6_frag.memerr);
return ERR_MEM;
}
pbuf_ref(p);
pcr->original = p;
pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom;
/* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
* so that it is removed when pbuf_dechain is later called on rambuf.
*/
pbuf_cat(rambuf, newpbuf);
left_to_copy -= newpbuflen;
if (left_to_copy) {
p = p->next;
}
}
poff = newpbuflen;
/* Set headers */
frag_hdr->_nexth = original_ip6hdr->_nexth;
frag_hdr->reserved = 0;
frag_hdr->_fragment_offset = htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG));
frag_hdr->_identification = htonl(identification);
IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT);
IP6H_PLEN_SET(ip6hdr, cop + IP6_FRAG_HLEN);
/* No need for separate header pbuf - we allowed room for it in rambuf
* when allocated.
*/
IP6_FRAG_STATS_INC(ip6_frag.xmit);
netif->output_ip6(netif, rambuf, dest);
/* Unfortunately we can't reuse rambuf - the hardware may still be
* using the buffer. Instead we free it (and the ensuing chain) and
* recreate it next time round the loop. If we're lucky the hardware
* will have already sent the packet, the free will really free, and
* there will be zero memory penalty.
*/
pbuf_free(rambuf);
left -= cop;
fragment_offset += cop;
}
return ERR_OK;
}
#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */

View file

@ -1,588 +0,0 @@
/**
* @file
*
* Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710.
* No support for MLDv2.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
/* Based on igmp.c implementation of igmp v2 protocol */
#include "lwip/opt.h"
#if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */
#include "lwip/mld6.h"
#include "lwip/icmp6.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/ip.h"
#include "lwip/inet_chksum.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include <string.h>
/*
* MLD constants
*/
#define MLD6_HL 1
#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500)
#define MLD6_GROUP_NON_MEMBER 0
#define MLD6_GROUP_DELAYING_MEMBER 1
#define MLD6_GROUP_IDLE_MEMBER 2
/* The list of joined groups. */
static struct mld_group* mld_group_list;
/* Forward declarations. */
static struct mld_group * mld6_new_group(struct netif *ifp, const ip6_addr_t *addr);
static err_t mld6_free_group(struct mld_group *group);
static void mld6_delayed_report(struct mld_group *group, u16_t maxresp);
static void mld6_send(struct mld_group *group, u8_t type);
/**
* Stop MLD processing on interface
*
* @param netif network interface on which stop MLD processing
*/
err_t
mld6_stop(struct netif *netif)
{
struct mld_group *group = mld_group_list;
struct mld_group *prev = NULL;
struct mld_group *next;
/* look for groups joined on this interface further down the list */
while (group != NULL) {
next = group->next;
/* is it a group joined on this interface? */
if (group->netif == netif) {
/* is it the first group of the list? */
if (group == mld_group_list) {
mld_group_list = next;
}
/* is there a "previous" group defined? */
if (prev != NULL) {
prev->next = next;
}
/* disable the group at the MAC level */
if (netif->mld_mac_filter != NULL) {
netif->mld_mac_filter(netif, &(group->group_address), MLD6_DEL_MAC_FILTER);
}
/* free group */
memp_free(MEMP_MLD6_GROUP, group);
} else {
/* change the "previous" */
prev = group;
}
/* move to "next" */
group = next;
}
return ERR_OK;
}
/**
* Report MLD memberships for this interface
*
* @param netif network interface on which report MLD memberships
*/
void
mld6_report_groups(struct netif *netif)
{
struct mld_group *group = mld_group_list;
while (group != NULL) {
if (group->netif == netif) {
mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
}
group = group->next;
}
}
/**
* Search for a group that is joined on a netif
*
* @param ifp the network interface for which to look
* @param addr the group ipv6 address to search for
* @return a struct mld_group* if the group has been found,
* NULL if the group wasn't found.
*/
struct mld_group *
mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr)
{
struct mld_group *group = mld_group_list;
while (group != NULL) {
if ((group->netif == ifp) && (ip6_addr_cmp(&(group->group_address), addr))) {
return group;
}
group = group->next;
}
return NULL;
}
/**
* create a new group
*
* @param ifp the network interface for which to create
* @param addr the new group ipv6
* @return a struct mld_group*,
* NULL on memory error.
*/
static struct mld_group *
mld6_new_group(struct netif *ifp, const ip6_addr_t *addr)
{
struct mld_group *group;
group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP);
if (group != NULL) {
group->netif = ifp;
ip6_addr_set(&(group->group_address), addr);
group->timer = 0; /* Not running */
group->group_state = MLD6_GROUP_IDLE_MEMBER;
group->last_reporter_flag = 0;
group->use = 0;
group->next = mld_group_list;
mld_group_list = group;
}
return group;
}
/**
* Remove a group in the mld_group_list and free
*
* @param group the group to remove
* @return ERR_OK if group was removed from the list, an err_t otherwise
*/
static err_t
mld6_free_group(struct mld_group *group)
{
err_t err = ERR_OK;
/* Is it the first group? */
if (mld_group_list == group) {
mld_group_list = group->next;
} else {
/* look for group further down the list */
struct mld_group *tmpGroup;
for (tmpGroup = mld_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) {
if (tmpGroup->next == group) {
tmpGroup->next = group->next;
break;
}
}
/* Group not find group */
if (tmpGroup == NULL) {
err = ERR_ARG;
}
}
/* free group */
memp_free(MEMP_MLD6_GROUP, group);
return err;
}
/**
* Process an input MLD message. Called by icmp6_input.
*
* @param p the mld packet, p->payload pointing to the icmpv6 header
* @param inp the netif on which this packet was received
*/
void
mld6_input(struct pbuf *p, struct netif *inp)
{
struct mld_header * mld_hdr;
struct mld_group* group;
MLD6_STATS_INC(mld6.recv);
/* Check that mld header fits in packet. */
if (p->len < sizeof(struct mld_header)) {
/* TODO debug message */
pbuf_free(p);
MLD6_STATS_INC(mld6.lenerr);
MLD6_STATS_INC(mld6.drop);
return;
}
mld_hdr = (struct mld_header *)p->payload;
switch (mld_hdr->type) {
case ICMP6_TYPE_MLQ: /* Multicast listener query. */
/* Is it a general query? */
if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) &&
ip6_addr_isany(&(mld_hdr->multicast_address))) {
MLD6_STATS_INC(mld6.rx_general);
/* Report all groups, except all nodes group, and if-local groups. */
group = mld_group_list;
while (group != NULL) {
if ((group->netif == inp) &&
(!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
(!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
mld6_delayed_report(group, mld_hdr->max_resp_delay);
}
group = group->next;
}
} else {
/* Have we joined this group?
* We use IP6 destination address to have a memory aligned copy.
* mld_hdr->multicast_address should be the same. */
MLD6_STATS_INC(mld6.rx_group);
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
if (group != NULL) {
/* Schedule a report. */
mld6_delayed_report(group, mld_hdr->max_resp_delay);
}
}
break; /* ICMP6_TYPE_MLQ */
case ICMP6_TYPE_MLR: /* Multicast listener report. */
/* Have we joined this group?
* We use IP6 destination address to have a memory aligned copy.
* mld_hdr->multicast_address should be the same. */
MLD6_STATS_INC(mld6.rx_report);
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
if (group != NULL) {
/* If we are waiting to report, cancel it. */
if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
group->timer = 0; /* stopped */
group->group_state = MLD6_GROUP_IDLE_MEMBER;
group->last_reporter_flag = 0;
}
}
break; /* ICMP6_TYPE_MLR */
case ICMP6_TYPE_MLD: /* Multicast listener done. */
/* Do nothing, router will query us. */
break; /* ICMP6_TYPE_MLD */
default:
MLD6_STATS_INC(mld6.proterr);
MLD6_STATS_INC(mld6.drop);
break;
}
pbuf_free(p);
}
/**
* Join a group on a network interface.
*
* @param srcaddr ipv6 address of the network interface which should
* join a new group. If IP6_ADDR_ANY, join on all netifs
* @param groupaddr the ipv6 address of the group to join
* @return ERR_OK if group was joined on the netif(s), an err_t otherwise
*/
err_t
mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct netif *netif;
/* loop through netif's */
netif = netif_list;
while (netif != NULL) {
/* Should we join this interface ? */
if (ip6_addr_isany(srcaddr) ||
netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
err = mld6_joingroup_netif(netif, groupaddr);
if (err != ERR_OK) {
return err;
}
}
/* proceed to next network interface */
netif = netif->next;
}
return err;
}
/**
* Join a group on a network interface.
*
* @param netif the network interface which should join a new group.
* @param groupaddr the ipv6 address of the group to join
* @return ERR_OK if group was joined on the netif, an err_t otherwise
*/
err_t
mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
{
struct mld_group *group;
/* find group or create a new one if not found */
group = mld6_lookfor_group(netif, groupaddr);
if (group == NULL) {
/* Joining a new group. Create a new group entry. */
group = mld6_new_group(netif, groupaddr);
if (group == NULL) {
return ERR_MEM;
}
/* Activate this address on the MAC layer. */
if (netif->mld_mac_filter != NULL) {
netif->mld_mac_filter(netif, groupaddr, MLD6_ADD_MAC_FILTER);
}
/* Report our membership. */
MLD6_STATS_INC(mld6.tx_report);
mld6_send(group, ICMP6_TYPE_MLR);
mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
}
/* Increment group use */
group->use++;
return ERR_OK;
}
/**
* Leave a group on a network interface.
*
* @param srcaddr ipv6 address of the network interface which should
* leave the group. If IP6_ISANY, leave on all netifs
* @param groupaddr the ipv6 address of the group to leave
* @return ERR_OK if group was left on the netif(s), an err_t otherwise
*/
err_t
mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct netif *netif;
/* loop through netif's */
netif = netif_list;
while (netif != NULL) {
/* Should we leave this interface ? */
if (ip6_addr_isany(srcaddr) ||
netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
err_t res = mld6_leavegroup_netif(netif, groupaddr);
if (err != ERR_OK) {
/* Store this result if we have not yet gotten a success */
err = res;
}
}
/* proceed to next network interface */
netif = netif->next;
}
return err;
}
/**
* Leave a group on a network interface.
*
* @param netif the network interface which should leave the group.
* @param groupaddr the ipv6 address of the group to leave
* @return ERR_OK if group was left on the netif, an err_t otherwise
*/
err_t
mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
{
struct mld_group *group;
/* find group */
group = mld6_lookfor_group(netif, groupaddr);
if (group != NULL) {
/* Leave if there is no other use of the group */
if (group->use <= 1) {
/* If we are the last reporter for this group */
if (group->last_reporter_flag) {
MLD6_STATS_INC(mld6.tx_leave);
mld6_send(group, ICMP6_TYPE_MLD);
}
/* Disable the group at the MAC level */
if (netif->mld_mac_filter != NULL) {
netif->mld_mac_filter(netif, groupaddr, MLD6_DEL_MAC_FILTER);
}
/* Free the group */
mld6_free_group(group);
} else {
/* Decrement group use */
group->use--;
}
/* Left group */
return ERR_OK;
}
/* Group not found */
return ERR_VAL;
}
/**
* Periodic timer for mld processing. Must be called every
* MLD6_TMR_INTERVAL milliseconds (100).
*
* When a delaying member expires, a membership report is sent.
*/
void
mld6_tmr(void)
{
struct mld_group *group = mld_group_list;
while (group != NULL) {
if (group->timer > 0) {
group->timer--;
if (group->timer == 0) {
/* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */
if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
MLD6_STATS_INC(mld6.tx_report);
mld6_send(group, ICMP6_TYPE_MLR);
group->group_state = MLD6_GROUP_IDLE_MEMBER;
}
}
}
group = group->next;
}
}
/**
* Schedule a delayed membership report for a group
*
* @param group the mld_group for which "delaying" membership report
* should be sent
* @param maxresp the max resp delay provided in the query
*/
static void
mld6_delayed_report(struct mld_group *group, u16_t maxresp)
{
/* Convert maxresp from milliseconds to tmr ticks */
maxresp = maxresp / MLD6_TMR_INTERVAL;
if (maxresp == 0) {
maxresp = 1;
}
#ifdef LWIP_RAND
/* Randomize maxresp. (if LWIP_RAND is supported) */
maxresp = LWIP_RAND() % maxresp;
if (maxresp == 0) {
maxresp = 1;
}
#endif /* LWIP_RAND */
/* Apply timer value if no report has been scheduled already. */
if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
((group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
((group->timer == 0) || (maxresp < group->timer)))) {
group->timer = maxresp;
group->group_state = MLD6_GROUP_DELAYING_MEMBER;
}
}
/**
* Send a MLD message (report or done).
*
* An IPv6 hop-by-hop options header with a router alert option
* is prepended.
*
* @param group the group to report or quit
* @param type ICMP6_TYPE_MLR (report) or ICMP6_TYPE_MLD (done)
*/
static void
mld6_send(struct mld_group *group, u8_t type)
{
struct mld_header * mld_hdr;
struct pbuf * p;
const ip6_addr_t * src_addr;
/* Allocate a packet. Size is MLD header + IPv6 Hop-by-hop options header. */
p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + sizeof(struct ip6_hbh_hdr), PBUF_RAM);
if (p == NULL) {
MLD6_STATS_INC(mld6.memerr);
return;
}
/* Move to make room for Hop-by-hop options header. */
if (pbuf_header(p, -IP6_HBH_HLEN)) {
pbuf_free(p);
MLD6_STATS_INC(mld6.lenerr);
return;
}
/* Select our source address. */
if (!ip6_addr_isvalid(netif_ip6_addr_state(group->netif, 0))) {
/* This is a special case, when we are performing duplicate address detection.
* We must join the multicast group, but we don't have a valid address yet. */
src_addr = IP6_ADDR_ANY6;
} else {
/* Use link-local address as source address. */
src_addr = netif_ip6_addr(group->netif, 0);
}
/* MLD message header pointer. */
mld_hdr = (struct mld_header *)p->payload;
/* Set fields. */
mld_hdr->type = type;
mld_hdr->code = 0;
mld_hdr->chksum = 0;
mld_hdr->max_resp_delay = 0;
mld_hdr->reserved = 0;
ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
#if CHECKSUM_GEN_ICMP6
IF__NETIF_CHECKSUM_ENABLED(group->netif, NETIF_CHECKSUM_GEN_ICMP6) {
mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
src_addr, &(group->group_address));
}
#endif /* CHECKSUM_GEN_ICMP6 */
/* Add hop-by-hop headers options: router alert with MLD value. */
ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD);
/* Send the packet out. */
MLD6_STATS_INC(mld6.xmit);
ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address),
MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, group->netif);
pbuf_free(p);
}
#endif /* LWIP_IPV6 */

File diff suppressed because it is too large Load diff

View file

@ -1,682 +0,0 @@
/**
* @file
* Dynamic memory manager
*
* This is a lightweight replacement for the standard C library malloc().
*
* If you want to use the standard C library malloc() instead, define
* MEM_LIBC_MALLOC to 1 in your lwipopts.h
*
* To let mem_malloc() use pools (prevents fragmentation and is much faster than
* a heap but might waste some memory), define MEM_USE_POOLS to 1, define
* MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list
* of pools like this (more pools can be added between _START and _END):
*
* Define three pools with sizes 256, 512, and 1512 bytes
* LWIP_MALLOC_MEMPOOL_START
* LWIP_MALLOC_MEMPOOL(20, 256)
* LWIP_MALLOC_MEMPOOL(10, 512)
* LWIP_MALLOC_MEMPOOL(5, 1512)
* LWIP_MALLOC_MEMPOOL_END
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
* Simon Goldschmidt
*
*/
#include "lwip/opt.h"
#if !MEM_LIBC_MALLOC /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/err.h"
#include <string.h>
#if MEM_USE_POOLS
#if MEMP_MEM_MALLOC
#error MEM_USE_POOLS and MEMP_MEM_MALLOC cannot be used together
#endif
/* lwIP head implemented with different sized pools */
/**
* Allocate memory: determine the smallest pool that is big enough
* to contain an element of 'size' and get an element from that pool.
*
* @param size the size in bytes of the memory needed
* @return a pointer to the allocated memory or NULL if the pool is empty
*/
void *
mem_malloc(mem_size_t size)
{
void *ret;
struct memp_malloc_helper *element;
memp_t poolnr;
mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) {
#if MEM_USE_POOLS_TRY_BIGGER_POOL
again:
#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */
/* is this pool big enough to hold an element of the required size
plus a struct memp_malloc_helper that saves the pool this element came from? */
if (required_size <= memp_pools[poolnr]->size) {
break;
}
}
if (poolnr > MEMP_POOL_LAST) {
LWIP_ASSERT("mem_malloc(): no pool is that big!", 0);
return NULL;
}
element = (struct memp_malloc_helper*)memp_malloc(poolnr);
if (element == NULL) {
/* No need to DEBUGF or ASSERT: This error is already
taken care of in memp.c */
#if MEM_USE_POOLS_TRY_BIGGER_POOL
/** Try a bigger pool if this one is empty! */
if (poolnr < MEMP_POOL_LAST) {
poolnr++;
goto again;
}
#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */
return NULL;
}
/* save the pool number this element came from */
element->poolnr = poolnr;
/* and return a pointer to the memory directly after the struct memp_malloc_helper */
ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
#if MEMP_OVERFLOW_CHECK
/* initialize unused memory */
element->size = size;
memset((u8_t*)ret + size, 0xcd, memp_pools[poolnr]->size - size);
#endif /* MEMP_OVERFLOW_CHECK */
return ret;
}
/**
* Free memory previously allocated by mem_malloc. Loads the pool number
* and calls memp_free with that pool number to put the element back into
* its pool
*
* @param rmem the memory element to free
*/
void
mem_free(void *rmem)
{
struct memp_malloc_helper *hmem;
LWIP_ASSERT("rmem != NULL", (rmem != NULL));
LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem)));
/* get the original struct memp_malloc_helper */
hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)));
LWIP_ASSERT("hmem != NULL", (hmem != NULL));
LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem)));
LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX));
#if MEMP_OVERFLOW_CHECK
{
u16_t i;
LWIP_ASSERT("MEM_USE_POOLS: invalid chunk size",
hmem->size <= memp_pools[hmem->poolnr]->size);
/* check that unused memory remained untouched */
for (i = hmem->size; i < memp_pools[hmem->poolnr]->size; i++) {
u8_t data = *((u8_t*)rmem + i);
LWIP_ASSERT("MEM_USE_POOLS: mem overflow detected", data == 0xcd);
}
}
#endif /* MEMP_OVERFLOW_CHECK */
/* and put it in the pool we saved earlier */
memp_free(hmem->poolnr, hmem);
}
#else /* MEM_USE_POOLS */
/* lwIP replacement for your libc malloc() */
/**
* The heap is made up as a list of structs of this type.
* This does not have to be aligned since for getting its size,
* we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns.
*/
struct mem {
/** index (-> ram[next]) of the next struct */
mem_size_t next;
/** index (-> ram[prev]) of the previous struct */
mem_size_t prev;
/** 1: this area is used; 0: this area is unused */
u8_t used;
};
/** All allocated blocks will be MIN_SIZE bytes big, at least!
* MIN_SIZE can be overridden to suit your needs. Smaller values save space,
* larger values could prevent too small blocks to fragment the RAM too much. */
#ifndef MIN_SIZE
#define MIN_SIZE 12
#endif /* MIN_SIZE */
/* some alignment macros: we define them here for better source code layout */
#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE)
#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))
#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE)
/** If you want to relocate the heap to external memory, simply define
* LWIP_RAM_HEAP_POINTER as a void-pointer to that location.
* If so, make sure the memory at that location is big enough (see below on
* how that space is calculated). */
#ifndef LWIP_RAM_HEAP_POINTER
/** the heap. we need one struct mem at the end and some room for alignment */
u8_t ram_heap[MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT];
#define LWIP_RAM_HEAP_POINTER ram_heap
#endif /* LWIP_RAM_HEAP_POINTER */
/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */
static u8_t *ram;
/** the last entry, always unused! */
static struct mem *ram_end;
/** pointer to the lowest free block, this is used for faster search */
static struct mem *lfree;
/** concurrent access protection */
#if !NO_SYS
static sys_mutex_t mem_mutex;
#endif
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
static volatile u8_t mem_free_count;
/* Allow mem_free from other (e.g. interrupt) context */
#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free)
#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free)
#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free)
#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc)
#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc)
#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc)
#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
/* Protect the heap only by using a semaphore */
#define LWIP_MEM_FREE_DECL_PROTECT()
#define LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex)
#define LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex)
/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */
#define LWIP_MEM_ALLOC_DECL_PROTECT()
#define LWIP_MEM_ALLOC_PROTECT()
#define LWIP_MEM_ALLOC_UNPROTECT()
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
/**
* "Plug holes" by combining adjacent empty struct mems.
* After this function is through, there should not exist
* one empty struct mem pointing to another empty struct mem.
*
* @param mem this points to a struct mem which just has been freed
* @internal this function is only called by mem_free() and mem_trim()
*
* This assumes access to the heap is protected by the calling function
* already.
*/
static void
plug_holes(struct mem *mem)
{
struct mem *nmem;
struct mem *pmem;
LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
/* plug hole forward */
LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED);
nmem = (struct mem *)(void *)&ram[mem->next];
if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
/* if mem->next is unused and not end of ram, combine mem and mem->next */
if (lfree == nmem) {
lfree = mem;
}
mem->next = nmem->next;
((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram);
}
/* plug hole backward */
pmem = (struct mem *)(void *)&ram[mem->prev];
if (pmem != mem && pmem->used == 0) {
/* if mem->prev is unused, combine mem and mem->prev */
if (lfree == mem) {
lfree = pmem;
}
pmem->next = mem->next;
((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram);
}
}
/**
* Zero the heap and initialize start, end and lowest-free
*/
void
mem_init(void)
{
struct mem *mem;
LWIP_ASSERT("Sanity check alignment",
(SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0);
/* align the heap */
ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER);
/* initialize the start of the heap */
mem = (struct mem *)(void *)ram;
mem->next = MEM_SIZE_ALIGNED;
mem->prev = 0;
mem->used = 0;
/* initialize the end of the heap */
ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED];
ram_end->used = 1;
ram_end->next = MEM_SIZE_ALIGNED;
ram_end->prev = MEM_SIZE_ALIGNED;
/* initialize the lowest-free pointer to the start of the heap */
lfree = (struct mem *)(void *)ram;
MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED);
if (sys_mutex_new(&mem_mutex) != ERR_OK) {
LWIP_ASSERT("failed to create mem_mutex", 0);
}
}
/**
* Put a struct mem back on the heap
*
* @param rmem is the data portion of a struct mem as returned by a previous
* call to mem_malloc()
*/
void
mem_free(void *rmem)
{
struct mem *mem;
LWIP_MEM_FREE_DECL_PROTECT();
if (rmem == NULL) {
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n"));
return;
}
LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0);
LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
(u8_t *)rmem < (u8_t *)ram_end);
if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
SYS_ARCH_DECL_PROTECT(lev);
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n"));
/* protect mem stats from concurrent access */
SYS_ARCH_PROTECT(lev);
MEM_STATS_INC(illegal);
SYS_ARCH_UNPROTECT(lev);
return;
}
/* protect the heap from concurrent access */
LWIP_MEM_FREE_PROTECT();
/* Get the corresponding struct mem ... */
mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
/* ... which has to be in a used state ... */
LWIP_ASSERT("mem_free: mem->used", mem->used);
/* ... and is now unused. */
mem->used = 0;
if (mem < lfree) {
/* the newly freed struct is now the lowest */
lfree = mem;
}
MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram)));
/* finally, see if prev or next are free also */
plug_holes(mem);
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
mem_free_count = 1;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
LWIP_MEM_FREE_UNPROTECT();
}
/**
* Shrink memory returned by mem_malloc().
*
* @param rmem pointer to memory allocated by mem_malloc the is to be shrinked
* @param newsize required size after shrinking (needs to be smaller than or
* equal to the previous size)
* @return for compatibility reasons: is always == rmem, at the moment
* or NULL if newsize is > old size, in which case rmem is NOT touched
* or freed!
*/
void *
mem_trim(void *rmem, mem_size_t newsize)
{
mem_size_t size;
mem_size_t ptr, ptr2;
struct mem *mem, *mem2;
/* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */
LWIP_MEM_FREE_DECL_PROTECT();
/* Expand the size of the allocated memory region so that we can
adjust for alignment. */
newsize = LWIP_MEM_ALIGN_SIZE(newsize);
if (newsize < MIN_SIZE_ALIGNED) {
/* every data block must be at least MIN_SIZE_ALIGNED long */
newsize = MIN_SIZE_ALIGNED;
}
if (newsize > MEM_SIZE_ALIGNED) {
return NULL;
}
LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
(u8_t *)rmem < (u8_t *)ram_end);
if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
SYS_ARCH_DECL_PROTECT(lev);
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n"));
/* protect mem stats from concurrent access */
SYS_ARCH_PROTECT(lev);
MEM_STATS_INC(illegal);
SYS_ARCH_UNPROTECT(lev);
return rmem;
}
/* Get the corresponding struct mem ... */
mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
/* ... and its offset pointer */
ptr = (mem_size_t)((u8_t *)mem - ram);
size = mem->next - ptr - SIZEOF_STRUCT_MEM;
LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size);
if (newsize > size) {
/* not supported */
return NULL;
}
if (newsize == size) {
/* No change in size, simply return */
return rmem;
}
/* protect the heap from concurrent access */
LWIP_MEM_FREE_PROTECT();
mem2 = (struct mem *)(void *)&ram[mem->next];
if (mem2->used == 0) {
/* The next struct is unused, we can simply move it at little */
mem_size_t next;
/* remember the old next pointer */
next = mem2->next;
/* create new struct mem which is moved directly after the shrinked mem */
ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
if (lfree == mem2) {
lfree = (struct mem *)(void *)&ram[ptr2];
}
mem2 = (struct mem *)(void *)&ram[ptr2];
mem2->used = 0;
/* restore the next pointer */
mem2->next = next;
/* link it back to mem */
mem2->prev = ptr;
/* link mem to it */
mem->next = ptr2;
/* last thing to restore linked list: as we have moved mem2,
* let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not
* the end of the heap */
if (mem2->next != MEM_SIZE_ALIGNED) {
((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
}
MEM_STATS_DEC_USED(used, (size - newsize));
/* no need to plug holes, we've already done that */
} else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) {
/* Next struct is used but there's room for another struct mem with
* at least MIN_SIZE_ALIGNED of data.
* Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem
* ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED').
* @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
* region that couldn't hold data, but when mem->next gets freed,
* the 2 regions would be combined, resulting in more free memory */
ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
mem2 = (struct mem *)(void *)&ram[ptr2];
if (mem2 < lfree) {
lfree = mem2;
}
mem2->used = 0;
mem2->next = mem->next;
mem2->prev = ptr;
mem->next = ptr2;
if (mem2->next != MEM_SIZE_ALIGNED) {
((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
}
MEM_STATS_DEC_USED(used, (size - newsize));
/* the original mem->next is used, so no need to plug holes! */
}
/* else {
next struct mem is used but size between mem and mem2 is not big enough
to create another struct mem
-> don't do anyhting.
-> the remaining space stays unused since it is too small
} */
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
mem_free_count = 1;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
LWIP_MEM_FREE_UNPROTECT();
return rmem;
}
/**
* Adam's mem_malloc() plus solution for bug #17922
* Allocate a block of memory with a minimum of 'size' bytes.
*
* @param size is the minimum size of the requested block in bytes.
* @return pointer to allocated memory or NULL if no free memory was found.
*
* Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT).
*/
void *
mem_malloc(mem_size_t size)
{
mem_size_t ptr, ptr2;
struct mem *mem, *mem2;
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
u8_t local_mem_free_count = 0;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
LWIP_MEM_ALLOC_DECL_PROTECT();
if (size == 0) {
return NULL;
}
/* Expand the size of the allocated memory region so that we can
adjust for alignment. */
size = LWIP_MEM_ALIGN_SIZE(size);
if (size < MIN_SIZE_ALIGNED) {
/* every data block must be at least MIN_SIZE_ALIGNED long */
size = MIN_SIZE_ALIGNED;
}
if (size > MEM_SIZE_ALIGNED) {
return NULL;
}
/* protect the heap from concurrent access */
sys_mutex_lock(&mem_mutex);
LWIP_MEM_ALLOC_PROTECT();
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
/* run as long as a mem_free disturbed mem_malloc or mem_trim */
do {
local_mem_free_count = 0;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
/* Scan through the heap searching for a free block that is big enough,
* beginning with the lowest free block.
*/
for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size;
ptr = ((struct mem *)(void *)&ram[ptr])->next) {
mem = (struct mem *)(void *)&ram[ptr];
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
mem_free_count = 0;
LWIP_MEM_ALLOC_UNPROTECT();
/* allow mem_free or mem_trim to run */
LWIP_MEM_ALLOC_PROTECT();
if (mem_free_count != 0) {
/* If mem_free or mem_trim have run, we have to restart since they
could have altered our current struct mem. */
local_mem_free_count = 1;
break;
}
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
if ((!mem->used) &&
(mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
/* mem is not used and at least perfect fit is possible:
* mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
/* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
* at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
* -> split large block, create empty remainder,
* remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
* mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
* struct mem would fit in but no data between mem2 and mem2->next
* @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
* region that couldn't hold data, but when mem->next gets freed,
* the 2 regions would be combined, resulting in more free memory
*/
ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
/* create mem2 struct */
mem2 = (struct mem *)(void *)&ram[ptr2];
mem2->used = 0;
mem2->next = mem->next;
mem2->prev = ptr;
/* and insert it between mem and mem->next */
mem->next = ptr2;
mem->used = 1;
if (mem2->next != MEM_SIZE_ALIGNED) {
((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
}
MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM));
} else {
/* (a mem2 struct does no fit into the user data space of mem and mem->next will always
* be used at this point: if not we have 2 unused structs in a row, plug_holes should have
* take care of this).
* -> near fit or exact fit: do not split, no mem2 creation
* also can't move mem->next directly behind mem, since mem->next
* will always be used at this point!
*/
mem->used = 1;
MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram));
}
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
mem_malloc_adjust_lfree:
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
if (mem == lfree) {
struct mem *cur = lfree;
/* Find next free block after mem and update lowest free pointer */
while (cur->used && cur != ram_end) {
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
mem_free_count = 0;
LWIP_MEM_ALLOC_UNPROTECT();
/* prevent high interrupt latency... */
LWIP_MEM_ALLOC_PROTECT();
if (mem_free_count != 0) {
/* If mem_free or mem_trim have run, we have to restart since they
could have altered our current struct mem or lfree. */
goto mem_malloc_adjust_lfree;
}
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
cur = (struct mem *)(void *)&ram[cur->next];
}
lfree = cur;
LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
}
LWIP_MEM_ALLOC_UNPROTECT();
sys_mutex_unlock(&mem_mutex);
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
(mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
LWIP_ASSERT("mem_malloc: sanity check alignment",
(((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
}
}
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
/* if we got interrupted by a mem_free, try again */
} while (local_mem_free_count != 0);
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
MEM_STATS_INC(err);
LWIP_MEM_ALLOC_UNPROTECT();
sys_mutex_unlock(&mem_mutex);
return NULL;
}
#endif /* MEM_USE_POOLS */
/**
* Contiguously allocates enough space for count objects that are size bytes
* of memory each and returns a pointer to the allocated memory.
*
* The allocated memory is filled with bytes of value zero.
*
* @param count number of objects to allocate
* @param size size of the objects to allocate
* @return pointer to allocated memory / NULL pointer if there is an error
*/
void *mem_calloc(mem_size_t count, mem_size_t size)
{
void *p;
/* allocate 'count' objects of size 'size' */
p = mem_malloc(count * size);
if (p) {
/* zero the memory */
memset(p, 0, (size_t)count * (size_t)size);
}
return p;
}
#endif /* !MEM_LIBC_MALLOC */

View file

@ -1,432 +0,0 @@
/**
* @file
* Dynamic pool memory manager
*
* lwIP has dedicated pools for many structures (netconn, protocol control blocks,
* packet buffers, ...). All these pools are managed here.
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/raw.h"
#include "lwip/igmp.h"
#include "lwip/api.h"
#include "lwip/priv/api_msg.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/timers.h"
#include "lwip/stats.h"
#include "netif/etharp.h"
#include "lwip/ip_frag.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "netif/ppp/ppp.h"
#include "netif/ppp/pppos.h"
#include "netif/ppp/pppoe.h"
#include "netif/ppp/pppol2tp.h"
#include "lwip/nd6.h"
#include "lwip/ip6_frag.h"
#include "lwip/mld6.h"
#include "lwip/tcp.h"
#include "lwip/tcpip.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/netifapi.h"
#include <string.h>
#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
#include "lwip/priv/memp_std.h"
const struct memp_desc* const memp_pools[MEMP_MAX] = {
#define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name,
#include "lwip/priv/memp_std.h"
};
#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
#if MEMP_SANITY_CHECK
/**
* Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm".
*/
static int
memp_sanity(const struct memp_desc *desc)
{
struct memp *t, *h;
t = *desc->tab;
if (t != NULL) {
for (h = t->next; (t != NULL) && (h != NULL); t = t->next,
h = ((h->next != NULL) ? h->next->next : NULL)) {
if (t == h) {
return 0;
}
}
}
return 1;
}
#endif /* MEMP_SANITY_CHECK*/
#if MEMP_OVERFLOW_CHECK
/**
* Check if a memp element was victim of an overflow
* (e.g. the restricted area after it has been altered)
*
* @param p the memp element to check
* @param memp_type the pool p comes from
*/
static void
memp_overflow_check_element_overflow(struct memp *p, const struct memp_desc *desc)
{
u16_t k;
u8_t *m;
#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
m = (u8_t*)p + MEMP_SIZE + desc->size;
for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
if (m[k] != 0xcd) {
char errstr[128] = "detected memp overflow in pool ";
strcat(errstr, desc->desc);
LWIP_ASSERT(errstr, 0);
}
}
#endif
}
/**
* Check if a memp element was victim of an underflow
* (e.g. the restricted area before it has been altered)
*
* @param p the memp element to check
* @param memp_type the pool p comes from
*/
static void
memp_overflow_check_element_underflow(struct memp *p, const struct memp_desc *desc)
{
u16_t k;
u8_t *m;
#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) {
if (m[k] != 0xcd) {
char errstr[128] = "detected memp underflow in pool ";
strcat(errstr, desc->desc);
LWIP_ASSERT(errstr, 0);
}
}
#endif
}
/**
* Do an overflow check for all elements in every pool.
*
* @see memp_overflow_check_element for a description of the check
*/
static void
memp_overflow_check_all(void)
{
u16_t i, j;
struct memp *p;
for (i = 0; i < MEMP_MAX; ++i) {
p = (struct memp *)(size_t)(memp_pools[i]->base);
for (j = 0; j < memp_pools[i]->num; ++j) {
memp_overflow_check_element_overflow(p, memp_pools[i]);
memp_overflow_check_element_underflow(p, memp_pools[i]);
p = (struct memp*)(size_t)((u8_t*)p + MEMP_SIZE + memp_pools[i]->size + MEMP_SANITY_REGION_AFTER_ALIGNED);
}
}
}
/**
* Initialize the restricted areas of all memp elements in every pool.
*/
static void
memp_overflow_init(const struct memp_desc *desc)
{
u16_t i;
struct memp *p;
u8_t *m;
p = (struct memp *)(size_t)(desc->base);
for (i = 0; i < desc->num; ++i) {
#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
#endif
#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
m = (u8_t*)p + MEMP_SIZE + desc->size;
memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
#endif
p = (struct memp*)(size_t)((u8_t*)p + MEMP_SIZE + desc->size + MEMP_SANITY_REGION_AFTER_ALIGNED);
}
}
#endif /* MEMP_OVERFLOW_CHECK */
void
memp_init_pool(const struct memp_desc *desc)
{
int i;
struct memp *memp;
*desc->tab = NULL;
memp = (struct memp*)LWIP_MEM_ALIGN(desc->base);
/* create a linked list of memp elements */
for (i = 0; i < desc->num; ++i) {
memp->next = *desc->tab;
*desc->tab = memp;
memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + desc->size
#if MEMP_OVERFLOW_CHECK
+ MEMP_SANITY_REGION_AFTER_ALIGNED
#endif
);
}
#if MEMP_OVERFLOW_CHECK
memp_overflow_init(desc);
#endif /* MEMP_OVERFLOW_CHECK */
}
/**
* Initialize this module.
*
* Carves out memp_memory into linked lists for each pool-type.
*/
void
memp_init(void)
{
u16_t i;
for (i = 0; i < MEMP_MAX; ++i) {
MEMP_STATS_AVAIL(used, i, 0);
MEMP_STATS_AVAIL(max, i, 0);
MEMP_STATS_AVAIL(err, i, 0);
MEMP_STATS_AVAIL(avail, i, memp_pools[i]->num);
}
/* for every pool: */
for (i = 0; i < MEMP_MAX; ++i) {
memp_init_pool(memp_pools[i]);
}
#if MEMP_OVERFLOW_CHECK
/* check everything a first time to see if it worked */
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK */
}
void *
#if !MEMP_OVERFLOW_CHECK
memp_malloc_pool(const struct memp_desc *desc)
#else
memp_malloc_pool_fn(const struct memp_desc *desc, const char* file, const int line)
#endif
{
struct memp *memp;
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
memp = *desc->tab;
#if MEMP_OVERFLOW_CHECK == 1
memp_overflow_check_element_overflow(memp, desc);
memp_overflow_check_element_underflow(memp, desc);
#endif /* MEMP_OVERFLOW_CHECK */
if (memp != NULL) {
*desc->tab = memp->next;
#if MEMP_OVERFLOW_CHECK
memp->next = NULL;
memp->file = file;
memp->line = line;
#endif /* MEMP_OVERFLOW_CHECK */
LWIP_ASSERT("memp_malloc: memp properly aligned",
((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);
}
SYS_ARCH_UNPROTECT(old_level);
return memp;
}
/**
* Get an element from a specific pool.
*
* @param type the pool to get an element from
*
* the debug version has two more parameters:
* @param file file name calling this function
* @param line number of line where this function is called
*
* @return a pointer to the allocated memory or a NULL pointer on error
*/
void *
#if !MEMP_OVERFLOW_CHECK
memp_malloc(memp_t type)
#else
memp_malloc_fn(memp_t type, const char* file, const int line)
#endif
{
void *memp;
SYS_ARCH_DECL_PROTECT(old_level);
LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
SYS_ARCH_PROTECT(old_level);
#if MEMP_OVERFLOW_CHECK >= 2
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
#if !MEMP_OVERFLOW_CHECK
memp = memp_malloc_pool(memp_pools[type]);
#else
memp = memp_malloc_pool_fn(memp_pools[type], file, line);
#endif
if (memp != NULL) {
MEMP_STATS_INC(used, type);
if(MEMP_STATS_GET(used, type) > MEMP_STATS_GET(max, type)) {
MEMP_STATS_AVAIL(max, type, MEMP_STATS_GET(used, type));
}
} else {
LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_pools[type]->desc));
MEMP_STATS_INC(err, type);
}
SYS_ARCH_UNPROTECT(old_level);
return memp;
}
static void
#ifdef LWIP_HOOK_MEMP_AVAILABLE
do_memp_free_pool(const struct memp_desc* desc, void *mem, struct memp **old_first)
#else
do_memp_free_pool(const struct memp_desc* desc, void *mem)
#endif
{
struct memp *memp;
SYS_ARCH_DECL_PROTECT(old_level);
LWIP_ASSERT("memp_free: mem properly aligned",
((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE);
SYS_ARCH_PROTECT(old_level);
#if MEMP_OVERFLOW_CHECK == 1
memp_overflow_check_element_overflow(memp, desc);
memp_overflow_check_element_underflow(memp, desc);
#endif /* MEMP_OVERFLOW_CHECK */
memp->next = *desc->tab;
#ifdef LWIP_HOOK_MEMP_AVAILABLE
if (old_first)
*old_first = *desc->tab;
#endif
*desc->tab = memp;
#if MEMP_SANITY_CHECK
LWIP_ASSERT("memp sanity", memp_sanity(desc));
#endif /* MEMP_SANITY_CHECK */
SYS_ARCH_UNPROTECT(old_level);
}
void
memp_free_pool(const struct memp_desc* desc, void *mem)
{
if ((desc == NULL) || (mem == NULL)) {
return;
}
#ifdef LWIP_HOOK_MEMP_AVAILABLE
do_memp_free_pool(desc, mem, NULL);
#else
do_memp_free_pool(desc, mem);
#endif
}
/**
* Put an element back into its pool.
*
* @param type the pool where to put mem
* @param mem the memp element to free
*/
void
memp_free(memp_t type, void *mem)
{
#ifdef LWIP_HOOK_MEMP_AVAILABLE
struct memp *old_first;
#endif
SYS_ARCH_DECL_PROTECT(old_level);
LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;);
SYS_ARCH_PROTECT(old_level);
#if MEMP_OVERFLOW_CHECK >= 2
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
MEMP_STATS_DEC(used, type);
#ifdef LWIP_HOOK_MEMP_AVAILABLE
do_memp_free_pool(memp_pools[type], mem, &old_first);
#else
do_memp_free_pool(memp_pools[type], mem);
#endif
SYS_ARCH_UNPROTECT(old_level);
#ifdef LWIP_HOOK_MEMP_AVAILABLE
if (old_first == NULL) {
LWIP_HOOK_MEMP_AVAILABLE(type);
}
#endif
}
#endif /* MEMP_MEM_MALLOC */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,479 +0,0 @@
/**
* @file
* Implementation of raw protocol PCBs for low-level handling of
* different types of protocols besides (or overriding) those
* already available in lwIP.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/raw.h"
#include "lwip/stats.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h"
#include <string.h>
/** The list of RAW PCBs */
static struct raw_pcb *raw_pcbs;
static u8_t
raw_input_match(struct raw_pcb *pcb, u8_t broadcast)
{
LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
/* Dual-stack: PCBs listening to any IP type also listen to any IP address */
if(IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
#if LWIP_IPV4 && IP_SOF_BROADCAST_RECV
if((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) {
return 0;
}
#endif /* LWIP_IPV4 && IP_SOF_BROADCAST_RECV */
return 1;
}
/* Only need to check PCB if incoming IP version matches PCB IP version */
if(IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) {
#if LWIP_IPV4
/* Special case: IPv4 broadcast: receive all broadcasts
* Note: broadcast variable can only be 1 if it is an IPv4 broadcast */
if(broadcast != 0) {
#if IP_SOF_BROADCAST_RECV
if(ip_get_option(pcb, SOF_BROADCAST))
#endif /* IP_SOF_BROADCAST_RECV */
{
if(ip4_addr_isany(ip_2_ip4(&pcb->local_ip))) {
return 1;
}
}
} else
#endif /* LWIP_IPV4 */
/* Handle IPv4 and IPv6: catch all or exact match */
if(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
return 1;
}
}
return 0;
}
/**
* Determine if in incoming IP packet is covered by a RAW PCB
* and if so, pass it to a user-provided receive callback function.
*
* Given an incoming IP datagram (as a chain of pbufs) this function
* finds a corresponding RAW PCB and calls the corresponding receive
* callback function.
*
* @param p pbuf to be demultiplexed to a RAW PCB.
* @param inp network interface on which the datagram was received.
* @return - 1 if the packet has been eaten by a RAW PCB receive
* callback function. The caller MAY NOT not reference the
* packet any longer, and MAY NOT call pbuf_free().
* @return - 0 if packet is not eaten (pbuf is still referenced by the
* caller).
*
*/
u8_t
raw_input(struct pbuf *p, struct netif *inp)
{
struct raw_pcb *pcb, *prev;
s16_t proto;
u8_t eaten = 0;
u8_t broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif());
LWIP_UNUSED_ARG(inp);
#if LWIP_IPV6
#if LWIP_IPV4
if (IP_HDR_GET_VERSION(p->payload) == 6)
#endif /* LWIP_IPV4 */
{
struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
proto = IP6H_NEXTH(ip6hdr);
}
#if LWIP_IPV4
else
#endif /* LWIP_IPV4 */
#endif /* LWIP_IPV6 */
#if LWIP_IPV4
{
proto = IPH_PROTO((struct ip_hdr *)p->payload);
}
#endif /* LWIP_IPV4 */
prev = NULL;
pcb = raw_pcbs;
/* loop through all raw pcbs until the packet is eaten by one */
/* this allows multiple pcbs to match against the packet by design */
while ((eaten == 0) && (pcb != NULL)) {
if ((pcb->protocol == proto) && raw_input_match(pcb, broadcast)) {
/* receive callback function available? */
if (pcb->recv != NULL) {
#ifndef LWIP_NOASSERT
void* old_payload = p->payload;
#endif
/* the receive callback function did not eat the packet? */
eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr());
if (eaten != 0) {
/* receive function ate the packet */
p = NULL;
eaten = 1;
if (prev != NULL) {
/* move the pcb to the front of raw_pcbs so that is
found faster next time */
prev->next = pcb->next;
pcb->next = raw_pcbs;
raw_pcbs = pcb;
}
} else {
/* sanity-check that the receive callback did not alter the pbuf */
LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet",
p->payload == old_payload);
}
}
/* no receive callback function was set for this raw PCB */
}
/* drop the packet */
prev = pcb;
pcb = pcb->next;
}
return eaten;
}
/**
* Bind a RAW PCB.
*
* @param pcb RAW PCB to be bound with a local address ipaddr.
* @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
* bind to all local interfaces.
*
* @return lwIP error code.
* - ERR_OK. Successful. No error occurred.
* - ERR_USE. The specified IP address is already bound to by
* another RAW PCB.
*
* @see raw_disconnect()
*/
err_t
raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
{
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) {
return ERR_VAL;
}
ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
return ERR_OK;
}
/**
* Connect an RAW PCB. This function is required by upper layers
* of lwip. Using the raw api you could use raw_sendto() instead
*
* This will associate the RAW PCB with the remote address.
*
* @param pcb RAW PCB to be connected with remote address ipaddr and port.
* @param ipaddr remote IP address to connect with.
*
* @return lwIP error code
*
* @see raw_disconnect() and raw_sendto()
*/
err_t
raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
{
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) {
return ERR_VAL;
}
ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
return ERR_OK;
}
/**
* Set the callback function for received packets that match the
* raw PCB's protocol and binding.
*
* The callback function MUST either
* - eat the packet by calling pbuf_free() and returning non-zero. The
* packet will not be passed to other raw PCBs or other protocol layers.
* - not free the packet, and return zero. The packet will be matched
* against further PCBs and/or forwarded to another protocol layers.
*
* @return non-zero if the packet was free()d, zero if the packet remains
* available for others.
*/
void
raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg)
{
/* remember recv() callback and user data */
pcb->recv = recv;
pcb->recv_arg = recv_arg;
}
/**
* Send the raw IP packet to the given address. Note that actually you cannot
* modify the IP headers (this is inconsistent with the receive callback where
* you actually get the IP headers), you can only specify the IP payload here.
* It requires some more changes in lwIP. (there will be a raw_send() function
* then.)
*
* @param pcb the raw pcb which to send
* @param p the IP payload to send
* @param ipaddr the destination address of the IP packet
*
*/
err_t
raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
{
err_t err;
struct netif *netif;
const ip_addr_t *src_ip;
struct pbuf *q; /* q will be sent down the stack */
s16_t header_size;
const ip_addr_t *dst_ip = ipaddr;
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
return ERR_VAL;
}
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
header_size = (
#if LWIP_IPV4 && LWIP_IPV6
IP_IS_V6(ipaddr) ? IP6_HLEN : IP_HLEN);
#elif LWIP_IPV4
IP_HLEN);
#else
IP6_HLEN);
#endif
/* not enough space to add an IP header to first pbuf in given p chain? */
if (pbuf_header(p, header_size)) {
/* allocate header in new pbuf */
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
return ERR_MEM;
}
if (p->tot_len != 0) {
/* chain header q in front of given pbuf p */
pbuf_chain(q, p);
}
/* { first pbuf q points to header pbuf } */
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
} else {
/* first pbuf q equals given pbuf */
q = p;
if (pbuf_header(q, -header_size)) {
LWIP_ASSERT("Can't restore header we just removed!", 0);
return ERR_MEM;
}
}
netif = ip_route(&pcb->local_ip, dst_ip);
if (netif == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, dst_ip);
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
#if IP_SOF_BROADCAST
if (!IP_IS_V6(ipaddr))
{
/* broadcast filter? */
if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_VAL;
}
}
#endif /* IP_SOF_BROADCAST */
if (ip_addr_isany(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = ip_netif_get_local_ip(netif, dst_ip);
#if LWIP_IPV6
if (src_ip == NULL) {
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
#endif /* LWIP_IPV6 */
} else {
/* use RAW PCB local IP address as source address */
src_ip = &pcb->local_ip;
}
#if LWIP_IPV6
/* If requested, based on the IPV6_CHECKSUM socket option per RFC3542,
compute the checksum and update the checksum in the payload. */
if (IP_IS_V6(dst_ip) && pcb->chksum_reqd) {
u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ip_2_ip6(src_ip), ip_2_ip6(dst_ip));
LWIP_ASSERT("Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2));
SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum, sizeof(u16_t));
}
#endif
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, pcb->protocol, netif);
NETIF_SET_HWADDRHINT(netif, NULL);
/* did we chain a header earlier? */
if (q != p) {
/* free the header */
pbuf_free(q);
}
return err;
}
/**
* Send the raw IP packet to the address given by raw_connect()
*
* @param pcb the raw pcb which to send
* @param p the IP payload to send
*
*/
err_t
raw_send(struct raw_pcb *pcb, struct pbuf *p)
{
return raw_sendto(pcb, p, &pcb->remote_ip);
}
/**
* Remove an RAW PCB.
*
* @param pcb RAW PCB to be removed. The PCB is removed from the list of
* RAW PCB's and the data structure is freed from memory.
*
* @see raw_new()
*/
void
raw_remove(struct raw_pcb *pcb)
{
struct raw_pcb *pcb2;
/* pcb to be removed is first in list? */
if (raw_pcbs == pcb) {
/* make list start at 2nd pcb */
raw_pcbs = raw_pcbs->next;
/* pcb not 1st in list */
} else {
for (pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
/* find pcb in raw_pcbs list */
if (pcb2->next != NULL && pcb2->next == pcb) {
/* remove pcb from list */
pcb2->next = pcb->next;
break;
}
}
}
memp_free(MEMP_RAW_PCB, pcb);
}
/**
* Create a RAW PCB.
*
* @return The RAW PCB which was created. NULL if the PCB data structure
* could not be allocated.
*
* @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP)
*
* @see raw_remove()
*/
struct raw_pcb *
raw_new(u8_t proto)
{
struct raw_pcb *pcb;
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n"));
pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB);
/* could allocate RAW PCB? */
if (pcb != NULL) {
/* initialize PCB to all zeroes */
memset(pcb, 0, sizeof(struct raw_pcb));
pcb->protocol = proto;
pcb->ttl = RAW_TTL;
pcb->next = raw_pcbs;
raw_pcbs = pcb;
}
return pcb;
}
/**
* Create a RAW PCB for IPv6.
*
* @return The RAW PCB which was created. NULL if the PCB data structure
* could not be allocated.
*
* @param type IP address type, see IPADDR_TYPE_XX definitions.
* @param proto the protocol number (next header) of the IPv6 packet payload
* (e.g. IP6_NEXTH_ICMP6)
*
* @see raw_remove()
*/
struct raw_pcb *
raw_new_ip_type(u8_t type, u8_t proto)
{
struct raw_pcb *pcb;
pcb = raw_new(proto);
#if LWIP_IPV4 && LWIP_IPV6
if(pcb != NULL) {
IP_SET_TYPE_VAL(pcb->local_ip, type);
IP_SET_TYPE_VAL(pcb->remote_ip, type);
}
#else /* LWIP_IPV4 && LWIP_IPV6 */
LWIP_UNUSED_ARG(type);
#endif /* LWIP_IPV4 && LWIP_IPV6 */
return pcb;
}
#endif /* LWIP_RAW */

View file

@ -1,202 +0,0 @@
/**
* @file
* Statistics module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/stats.h"
#include "lwip/mem.h"
#include "lwip/debug.h"
#include <string.h>
struct stats_ lwip_stats;
#if defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY
#if MEMP_STATS
static const char * memp_names[] = {
#define LWIP_MEMPOOL(name,num,size,desc) desc,
#include "lwip/priv/memp_std.h"
};
#endif /* MEMP_STATS */
#endif /* LWIP_DEBUG || LWIP_STATS_DISPLAY */
void
stats_init(void)
{
#ifdef LWIP_DEBUG
#if MEMP_STATS
int i;
for (i = 0; i < MEMP_MAX; i++) {
lwip_stats.memp[i].name = memp_names[i];
}
#endif /* MEMP_STATS */
#if MEM_STATS
lwip_stats.mem.name = "MEM";
#endif /* MEM_STATS */
#endif /* LWIP_DEBUG */
}
#if LWIP_STATS_DISPLAY
void
stats_display_proto(struct stats_proto *proto, const char *name)
{
LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit));
LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv));
LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw));
LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop));
LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr));
LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr));
LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr));
LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr));
LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr));
LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr));
LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err));
LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit));
}
#if IGMP_STATS || MLD6_STATS
void
stats_display_igmp(struct stats_igmp *igmp, const char *name)
{
LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit));
LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv));
LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop));
LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr));
LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr));
LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr));
LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr));
LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1));
LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group));
LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general));
LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report));
LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join));
LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave));
LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report));
}
#endif /* IGMP_STATS || MLD6_STATS */
#if MEM_STATS || MEMP_STATS
void
stats_display_mem(struct stats_mem *mem, const char *name)
{
LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name));
LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail));
LWIP_PLATFORM_DIAG(("used: %"U32_F"\n\t", (u32_t)mem->used));
LWIP_PLATFORM_DIAG(("max: %"U32_F"\n\t", (u32_t)mem->max));
LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err));
}
#if MEMP_STATS
void
stats_display_memp(struct stats_mem *mem, int index)
{
if (index < MEMP_MAX) {
stats_display_mem(mem, memp_names[index]);
}
}
#endif /* MEMP_STATS */
#endif /* MEM_STATS || MEMP_STATS */
#if SYS_STATS
void
stats_display_sys(struct stats_sys *sys)
{
LWIP_PLATFORM_DIAG(("\nSYS\n\t"));
LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used));
LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max));
LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err));
LWIP_PLATFORM_DIAG(("mutex.used: %"U32_F"\n\t", (u32_t)sys->mutex.used));
LWIP_PLATFORM_DIAG(("mutex.max: %"U32_F"\n\t", (u32_t)sys->mutex.max));
LWIP_PLATFORM_DIAG(("mutex.err: %"U32_F"\n\t", (u32_t)sys->mutex.err));
LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used));
LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max));
LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err));
}
#endif /* SYS_STATS */
void
stats_display(void)
{
s16_t i;
LINK_STATS_DISPLAY();
ETHARP_STATS_DISPLAY();
IPFRAG_STATS_DISPLAY();
IP6_FRAG_STATS_DISPLAY();
IP_STATS_DISPLAY();
ND6_STATS_DISPLAY();
IP6_STATS_DISPLAY();
IGMP_STATS_DISPLAY();
MLD6_STATS_DISPLAY();
ICMP_STATS_DISPLAY();
ICMP6_STATS_DISPLAY();
UDP_STATS_DISPLAY();
TCP_STATS_DISPLAY();
MEM_STATS_DISPLAY();
for (i = 0; i < MEMP_MAX; i++) {
MEMP_STATS_DISPLAY(i);
}
SYS_STATS_DISPLAY();
}
#endif /* LWIP_STATS_DISPLAY */
#if ESP_STATS_DROP
void stats_display_esp(struct stats_esp *esp)
{
LWIP_PLATFORM_DIAG(("\nESP\n\t"));
LWIP_PLATFORM_DIAG(("esp.rx_rawmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->rx_rawmbox_post_fail));
LWIP_PLATFORM_DIAG(("esp.rx_udpmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->rx_udpmbox_post_fail));
LWIP_PLATFORM_DIAG(("esp.rx_tcpmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->rx_tcpmbox_post_fail));
LWIP_PLATFORM_DIAG(("esp.err_tcp_rxmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->err_tcp_rxmbox_post_fail));
LWIP_PLATFORM_DIAG(("esp.err_tcp_acceptmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->err_tcp_acceptmbox_post_fail));
LWIP_PLATFORM_DIAG(("esp.acceptmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->acceptmbox_post_fail));
LWIP_PLATFORM_DIAG(("esp.free_mbox_post_fail: %"U32_F"\n\t", (u32_t)esp->free_mbox_post_fail));
LWIP_PLATFORM_DIAG(("esp.tcpip_inpkt_post_fail: %"U32_F"\n\t", (u32_t)esp->tcpip_inpkt_post_fail));
LWIP_PLATFORM_DIAG(("esp.tcpip_cb_post_fail: %"U32_F"\n\t", (u32_t)esp->tcpip_cb_post_fail));
LWIP_PLATFORM_DIAG(("esp.wlanif_input_pbuf_fail: %"U32_F"\n\t", (u32_t)esp->wlanif_input_pbuf_fail));
LWIP_PLATFORM_DIAG(("esp.wlanif_outut_pbuf_fail: %"U32_F"\n\t", (u32_t)esp->wlanif_outut_pbuf_fail));
}
#endif
#endif /* LWIP_STATS */

View file

@ -1,68 +0,0 @@
/**
* @file
* lwIP Operating System abstraction
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/sys.h"
/* Most of the functions defined in sys.h must be implemented in the
* architecture-dependent file sys_arch.c */
#if !NO_SYS
#ifndef sys_msleep
/**
* Sleep for some ms. Timeouts are NOT processed while sleeping.
*
* @param ms number of milliseconds to sleep
*/
void
sys_msleep(u32_t ms)
{
if (ms > 0) {
sys_sem_t delaysem;
err_t err = sys_sem_new(&delaysem, 0);
if (err == ERR_OK) {
sys_arch_sem_wait(&delaysem, ms);
sys_sem_free(&delaysem);
}
}
}
#endif /* sys_msleep */
#endif /* !NO_SYS */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,439 +0,0 @@
/**
* @file
* Stack-internal timers implementation.
* This file includes timer callbacks for stack-internal timers as well as
* functions to set up or stop timers and check for expired timers.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
* Simon Goldschmidt
*
*/
#include "lwip/opt.h"
#include "lwip/timers.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/ip_frag.h"
#include "netif/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/igmp.h"
#include "lwip/dns.h"
#include "lwip/nd6.h"
#include "lwip/ip6_frag.h"
#include "lwip/mld6.h"
#include "lwip/sys.h"
#include "lwip/pbuf.h"
#if LWIP_DEBUG_TIMERNAMES
#define HANDLER(x) x, #x
#else /* LWIP_DEBUG_TIMERNAMES */
#define HANDLER(x) x
#endif /* LWIP_DEBUG_TIMERNAMES */
#if ESP_DHCP
extern void dhcps_coarse_tmr(void);
#endif
/** This array contains all stack-internal cyclic timers. To get the number of
* timers, use LWIP_ARRAYSIZE() */
const struct lwip_cyclic_timer lwip_cyclic_timers[] = {
#if LWIP_TCP
/* The TCP timer is a special case: it does not have to run always and
* is triggered to start from TCP using tcp_timer_needed() */
{TCP_TMR_INTERVAL, HANDLER(tcp_tmr)},
#endif /* LWIP_TCP */
#if LWIP_IPV4
#if IP_REASSEMBLY
{IP_TMR_INTERVAL, HANDLER(ip_reass_tmr)},
#endif /* IP_REASSEMBLY */
#if LWIP_ARP
{ARP_TMR_INTERVAL, HANDLER(etharp_tmr)},
#endif /* LWIP_ARP */
#if LWIP_DHCP
{DHCP_COARSE_TIMER_MSECS, HANDLER(dhcp_coarse_tmr)},
{DHCP_FINE_TIMER_MSECS, HANDLER(dhcp_fine_tmr)},
#if ESP_DHCP
{DHCP_COARSE_TIMER_MSECS, HANDLER(dhcps_coarse_tmr)},
#endif
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
{AUTOIP_TMR_INTERVAL, HANDLER(autoip_tmr)},
#endif /* LWIP_AUTOIP */
#if LWIP_IGMP
{IGMP_TMR_INTERVAL, HANDLER(igmp_tmr)},
#endif /* LWIP_IGMP */
#endif /* LWIP_IPV4 */
#if LWIP_DNS
{DNS_TMR_INTERVAL, HANDLER(dns_tmr)},
#endif /* LWIP_DNS */
#if LWIP_IPV6
{ND6_TMR_INTERVAL, HANDLER(nd6_tmr)},
#if LWIP_IPV6_REASS
{IP6_REASS_TMR_INTERVAL, HANDLER(ip6_reass_tmr)},
#endif /* LWIP_IPV6_REASS */
#if LWIP_IPV6_MLD
{MLD6_TMR_INTERVAL, HANDLER(mld6_tmr)},
#endif /* LWIP_IPV6_MLD */
#endif /* LWIP_IPV6 */
};
#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM
/** The one and only timeout list */
static struct sys_timeo *next_timeout;
static u32_t timeouts_last_time;
#if LWIP_TCP
/** global variable that shows if the tcp timer is currently scheduled or not */
static int tcpip_tcp_timer_active;
/**
* Timer callback function that calls tcp_tmr() and reschedules itself.
*
* @param arg unused argument
*/
static void
tcpip_tcp_timer(void *arg)
{
LWIP_UNUSED_ARG(arg);
/* call TCP timer handler */
tcp_tmr();
/* timer still needed? */
if (tcp_active_pcbs || tcp_tw_pcbs) {
/* restart timer */
sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
} else {
/* disable timer */
tcpip_tcp_timer_active = 0;
}
}
/**
* Called from TCP_REG when registering a new PCB:
* the reason is to have the TCP timer only running when
* there are active (or time-wait) PCBs.
*/
void
tcp_timer_needed(void)
{
/* timer is off but needed again? */
if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
/* enable and start timer */
tcpip_tcp_timer_active = 1;
sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
}
}
#endif /* LWIP_TCP */
/**
* Timer callback function that calls mld6_tmr() and reschedules itself.
*
* @param arg unused argument
*/
static void
cyclic_timer(void *arg)
{
const struct lwip_cyclic_timer* cyclic = (const struct lwip_cyclic_timer*)arg;
#if LWIP_DEBUG_TIMERNAMES
LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: %s()\n", cyclic->handler_name));
#endif
cyclic->handler();
sys_timeout(cyclic->interval_ms, cyclic_timer, arg);
}
/** Initialize this module */
void sys_timeouts_init(void)
{
size_t i;
/* tcp_tmr() at index 0 is started on demand */
for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) {
/* we have to cast via size_t to get rid of const warning
* (this is OK as cyclic_timer() casts back to const* */
sys_timeout(lwip_cyclic_timers[i].interval_ms, cyclic_timer, LWIP_CONST_CAST(void*, &lwip_cyclic_timers[i]));
}
/* Initialise timestamp for sys_check_timeouts */
timeouts_last_time = sys_now();
}
/**
* Create a one-shot timer (aka timeout). Timeouts are processed in the
* following cases:
* - while waiting for a message using sys_timeouts_mbox_fetch()
* - by calling sys_check_timeouts() (NO_SYS==1 only)
*
* @param msecs time in milliseconds after that the timer should expire
* @param handler callback function to call when msecs have elapsed
* @param arg argument to pass to the callback function
*/
#if LWIP_DEBUG_TIMERNAMES
void
sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name)
#else /* LWIP_DEBUG_TIMERNAMES */
void
sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
#endif /* LWIP_DEBUG_TIMERNAMES */
{
struct sys_timeo *timeout, *t;
u32_t now, diff;
timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
if (timeout == NULL) {
LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
return;
}
now = sys_now();
if (next_timeout == NULL) {
diff = 0;
timeouts_last_time = now;
} else {
diff = now - timeouts_last_time;
}
timeout->next = NULL;
timeout->h = handler;
timeout->arg = arg;
timeout->time = msecs + diff;
#if LWIP_DEBUG_TIMERNAMES
timeout->handler_name = handler_name;
LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",
(void *)timeout, msecs, handler_name, (void *)arg));
#endif /* LWIP_DEBUG_TIMERNAMES */
if (next_timeout == NULL) {
next_timeout = timeout;
return;
}
if (next_timeout->time > msecs) {
next_timeout->time -= msecs;
timeout->next = next_timeout;
next_timeout = timeout;
} else {
for (t = next_timeout; t != NULL; t = t->next) {
timeout->time -= t->time;
if (t->next == NULL || t->next->time > timeout->time) {
if (t->next != NULL) {
t->next->time -= timeout->time;
} else if (timeout->time > msecs) {
/* If this is the case, 'timeouts_last_time' and 'now' differs too much.
* This can be due to sys_check_timeouts() not being called at the right
* times, but also when stopping in a breakpoint. Anyway, let's assume
* this is not wanted, so add the first timer's time instead of 'diff' */
timeout->time = msecs + next_timeout->time;
}
timeout->next = t->next;
t->next = timeout;
break;
}
}
}
}
/**
* Go through timeout list (for this task only) and remove the first matching
* entry (subsequent entries remain untouched), even though the timeout has not
* triggered yet.
*
* @param handler callback function that would be called by the timeout
* @param arg callback argument that would be passed to handler
*/
void
sys_untimeout(sys_timeout_handler handler, void *arg)
{
struct sys_timeo *prev_t, *t;
if (next_timeout == NULL) {
return;
}
for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
if ((t->h == handler) && (t->arg == arg)) {
/* We have a match */
/* Unlink from previous in list */
if (prev_t == NULL) {
next_timeout = t->next;
} else {
prev_t->next = t->next;
}
/* If not the last one, add time of this one back to next */
if (t->next != NULL) {
t->next->time += t->time;
}
memp_free(MEMP_SYS_TIMEOUT, t);
return;
}
}
return;
}
/**
* @ingroup lwip_nosys
* Handle timeouts for NO_SYS==1 (i.e. without using
* tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout
* handler functions when timeouts expire.
*
* Must be called periodically from your main loop.
*/
#if !NO_SYS && !defined __DOXYGEN__
static
#endif /* !NO_SYS */
void
sys_check_timeouts(void)
{
if (next_timeout) {
struct sys_timeo *tmptimeout;
u32_t diff;
sys_timeout_handler handler;
void *arg;
u8_t had_one;
u32_t now;
now = sys_now();
/* this cares for wraparounds */
diff = now - timeouts_last_time;
do {
PBUF_CHECK_FREE_OOSEQ();
had_one = 0;
tmptimeout = next_timeout;
if (tmptimeout && (tmptimeout->time <= diff)) {
/* timeout has expired */
had_one = 1;
timeouts_last_time += tmptimeout->time;
diff -= tmptimeout->time;
next_timeout = tmptimeout->next;
handler = tmptimeout->h;
arg = tmptimeout->arg;
#if LWIP_DEBUG_TIMERNAMES
if (handler != NULL) {
LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n",tmptimeout->handler_name, arg));
}
#endif /* LWIP_DEBUG_TIMERNAMES */
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
if (handler != NULL) {
#if !NO_SYS
/* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the
* timeout handler function. */
LOCK_TCPIP_CORE();
#endif /* !NO_SYS */
handler(arg);
#if !NO_SYS
UNLOCK_TCPIP_CORE();
#endif /* !NO_SYS */
}
LWIP_TCPIP_THREAD_ALIVE();
}
/* repeat until all expired timers have been called */
} while (had_one);
}
}
/** Set back the timestamp of the last call to sys_check_timeouts()
* This is necessary if sys_check_timeouts() hasn't been called for a long
* time (e.g. while saving energy) to prevent all timer functions of that
* period being called.
*/
void
sys_restart_timeouts(void)
{
timeouts_last_time = sys_now();
}
/** Return the time left before the next timeout is due. If no timeouts are
* enqueued, returns 0xffffffff
*/
#if !NO_SYS
static
#endif /* !NO_SYS */
u32_t
sys_timeouts_sleeptime(void)
{
u32_t diff;
if (next_timeout == NULL) {
return 0xffffffff;
}
diff = sys_now() - timeouts_last_time;
if (diff > next_timeout->time) {
return 0;
} else {
return next_timeout->time - diff;
}
}
#if !NO_SYS
/**
* Wait (forever) for a message to arrive in an mbox.
* While waiting, timeouts are processed.
*
* @param mbox the mbox to fetch the message from
* @param msg the place to store the message
*/
void ESP_IRAM_ATTR
sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
{
u32_t sleeptime;
again:
if (!next_timeout) {
sys_arch_mbox_fetch(mbox, msg, 0);
return;
}
sleeptime = sys_timeouts_sleeptime();
if (sleeptime == 0 || sys_arch_mbox_fetch(mbox, msg, sleeptime) == SYS_ARCH_TIMEOUT) {
/* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred
* before a message could be fetched. */
sys_check_timeouts();
/* We try again to fetch a message from the mbox. */
goto again;
}
}
#endif /* NO_SYS */
#else /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */
/* Satisfy the TCP code which calls this function */
void
tcp_timer_needed(void)
{
}
#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */

File diff suppressed because it is too large Load diff

View file

@ -1,71 +0,0 @@
/*
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Frédéric Bernon, Simon Goldschmidt
*
*/
#ifndef LWIP_HDR_APPS_SNTP_H
#define LWIP_HDR_APPS_SNTP_H
#include "apps/sntp/sntp_opts.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
/* SNTP operating modes: default is to poll using unicast.
The mode has to be set before calling sntp_init(). */
#define SNTP_OPMODE_POLL 0
#define SNTP_OPMODE_LISTENONLY 1
void sntp_setoperatingmode(u8_t operating_mode);
u8_t sntp_getoperatingmode(void);
void sntp_init(void);
void sntp_stop(void);
u8_t sntp_enabled(void);
void sntp_setserver(u8_t idx, const ip_addr_t *addr);
ip_addr_t sntp_getserver(u8_t idx);
#if SNTP_SERVER_DNS
void sntp_setservername(u8_t idx, char *server);
char *sntp_getservername(u8_t idx);
#endif /* SNTP_SERVER_DNS */
#if SNTP_GET_SERVERS_FROM_DHCP
void sntp_servermode_dhcp(int set_servers_from_dhcp);
#else /* SNTP_GET_SERVERS_FROM_DHCP */
#define sntp_servermode_dhcp(x)
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNTP_H */

View file

@ -1,159 +0,0 @@
/*
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Frédéric Bernon, Simon Goldschmidt
*
*/
#ifndef LWIP_HDR_APPS_SNTP_OPTS_H
#define LWIP_HDR_APPS_SNTP_OPTS_H
#include "lwip/opt.h"
/** SNTP macro to change system time in seconds
* Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds instead of this one
* if you need the additional precision.
*/
#ifndef SNTP_SET_SYSTEM_TIME
#define SNTP_SET_SYSTEM_TIME(sec) LWIP_UNUSED_ARG(sec)
#endif
/** The maximum number of SNTP servers that can be set */
#ifndef SNTP_MAX_SERVERS
#define SNTP_MAX_SERVERS LWIP_DHCP_MAX_NTP_SERVERS
#endif
/** Set this to 1 to implement the callback function called by dhcp when
* NTP servers are received. */
#ifndef SNTP_GET_SERVERS_FROM_DHCP
#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
#endif
/* Set this to 1 to support DNS names (or IP address strings) to set sntp servers */
#ifndef SNTP_SERVER_DNS
#define SNTP_SERVER_DNS 1
#endif
/** One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
* #define SNTP_SERVER_ADDRESS "pool.ntp.org"
*/
/**
* SNTP_DEBUG: Enable debugging for SNTP.
*/
#ifndef SNTP_DEBUG
#define SNTP_DEBUG LWIP_DBG_OFF
#endif
/** SNTP server port */
#ifndef SNTP_PORT
#define SNTP_PORT 123
#endif
/** Set this to 1 to allow config of SNTP server(s) by DNS name */
#ifndef SNTP_SERVER_DNS
#define SNTP_SERVER_DNS 0
#endif
/** Sanity check:
* Define this to
* - 0 to turn off sanity checks (default; smaller code)
* - >= 1 to check address and port of the response packet to ensure the
* response comes from the server we sent the request to.
* - >= 2 to check returned Originate Timestamp against Transmit Timestamp
* sent to the server (to ensure response to older request).
* - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp
* fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast).
* - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each
* greater than or equal to 0 and less than infinity, where infinity is
* currently a cozy number like one second. This check avoids using a
* server whose synchronization source has expired for a very long time.
*/
#ifndef SNTP_CHECK_RESPONSE
#define SNTP_CHECK_RESPONSE 0
#endif
/** According to the RFC, this shall be a random delay
* between 1 and 5 minutes (in milliseconds) to prevent load peaks.
* This can be defined to a random generation function,
* which must return the delay in milliseconds as u32_t.
* Turned off by default.
*/
#ifndef SNTP_STARTUP_DELAY
#define SNTP_STARTUP_DELAY 0
#endif
/** If you want the startup delay to be a function, define this
* to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1.
*/
#ifndef SNTP_STARTUP_DELAY_FUNC
#define SNTP_STARTUP_DELAY_FUNC SNTP_STARTUP_DELAY
#endif
/** SNTP receive timeout - in milliseconds
* Also used as retry timeout - this shouldn't be too low.
* Default is 3 seconds.
*/
#ifndef SNTP_RECV_TIMEOUT
#define SNTP_RECV_TIMEOUT 3000
#endif
/** SNTP update delay - in milliseconds
* Default is 1 hour. Must not be beolw 15 seconds by specification (i.e. 15000)
*/
#ifndef SNTP_UPDATE_DELAY
#define SNTP_UPDATE_DELAY 3600000
#endif
/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2
* to send in request and compare in response.
*/
#ifndef SNTP_GET_SYSTEM_TIME
#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0)
#endif
/** Default retry timeout (in milliseconds) if the response
* received is invalid.
* This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached.
*/
#ifndef SNTP_RETRY_TIMEOUT
#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT
#endif
/** Maximum retry timeout (in milliseconds). */
#ifndef SNTP_RETRY_TIMEOUT_MAX
#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10)
#endif
/** Increase retry timeout with every retry sent
* Default is on to conform to RFC.
*/
#ifndef SNTP_RETRY_TIMEOUT_EXP
#define SNTP_RETRY_TIMEOUT_EXP 1
#endif
#endif /* LWIP_HDR_APPS_SNTP_OPTS_H */

View file

@ -1,364 +0,0 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_API_H
#define LWIP_HDR_API_H
#include "lwip/opt.h"
#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
/* Note: Netconn API is always available when sockets are enabled -
* sockets are implemented on top of them */
#include <stddef.h> /* for size_t */
#include "lwip/netbuf.h"
#include "lwip/sys.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Throughout this file, IP addresses and port numbers are expected to be in
* the same byte order as in the corresponding pcb.
*/
/* Flags for netconn_write (u8_t) */
#define NETCONN_NOFLAG 0x00
#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */
#define NETCONN_COPY 0x01
#define NETCONN_MORE 0x02
#define NETCONN_DONTBLOCK 0x04
/* Flags for struct netconn.flags (u8_t) */
/** Should this netconn avoid blocking? */
#define NETCONN_FLAG_NON_BLOCKING 0x02
/** Was the last connect action a non-blocking one? */
#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04
/** If this is set, a TCP netconn must call netconn_recved() to update
the TCP receive window (done automatically if not set). */
#define NETCONN_FLAG_NO_AUTO_RECVED 0x08
/** If a nonblocking write has been rejected before, poll_tcp needs to
check if the netconn is writable again */
#define NETCONN_FLAG_CHECK_WRITESPACE 0x10
#if LWIP_IPV6
/** If this flag is set then only IPv6 communication is allowed on the
netconn. As per RFC#3493 this features defaults to OFF allowing
dual-stack usage by default. */
#define NETCONN_FLAG_IPV6_V6ONLY 0x20
#endif /* LWIP_IPV6 */
/* Helpers to process several netconn_types by the same code */
#define NETCONNTYPE_GROUP(t) ((t)&0xF0)
#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0)
#if LWIP_IPV6
#define NETCONN_TYPE_IPV6 0x08
#define NETCONNTYPE_ISIPV6(t) (((t)&NETCONN_TYPE_IPV6) != 0)
#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF3) == NETCONN_UDPLITE)
#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM)
#else /* LWIP_IPV6 */
#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE)
#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM)
#endif /* LWIP_IPV6 */
/** Protocol family and type of the netconn */
enum netconn_type {
NETCONN_INVALID = 0,
/* NETCONN_TCP Group */
NETCONN_TCP = 0x10,
#if LWIP_IPV6
NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */,
#endif /* LWIP_IPV6 */
/* NETCONN_UDP Group */
NETCONN_UDP = 0x20,
NETCONN_UDPLITE = 0x21,
NETCONN_UDPNOCHKSUM = 0x22,
#if LWIP_IPV6
NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */,
NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */,
NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */,
#endif /* LWIP_IPV6 */
/* NETCONN_RAW Group */
NETCONN_RAW = 0x40
#if LWIP_IPV6
, NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */
#endif /* LWIP_IPV6 */
};
/** Current state of the netconn. Non-TCP netconns are always
* in state NETCONN_NONE! */
enum netconn_state {
NETCONN_NONE,
NETCONN_WRITE,
NETCONN_LISTEN,
NETCONN_CONNECT,
NETCONN_CLOSE
};
/** Use to inform the callback function about changes */
enum netconn_evt {
NETCONN_EVT_RCVPLUS,
NETCONN_EVT_RCVMINUS,
NETCONN_EVT_SENDPLUS,
NETCONN_EVT_SENDMINUS,
NETCONN_EVT_ERROR
};
#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
/** Used for netconn_join_leave_group() */
enum netconn_igmp {
NETCONN_JOIN,
NETCONN_LEAVE
};
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
#if LWIP_DNS
/* Used for netconn_gethostbyname_addrtype(), these should match the DNS_ADDRTYPE defines in dns.h */
#define NETCONN_DNS_DEFAULT NETCONN_DNS_IPV4_IPV6
#define NETCONN_DNS_IPV4 0
#define NETCONN_DNS_IPV6 1
#define NETCONN_DNS_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */
#define NETCONN_DNS_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */
#endif /* LWIP_DNS */
/* forward-declare some structs to avoid to include their headers */
struct ip_pcb;
struct tcp_pcb;
struct udp_pcb;
struct raw_pcb;
struct netconn;
struct api_msg_msg;
/** A callback prototype to inform about events for a netconn */
typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len);
/** A netconn descriptor */
struct netconn {
/** type of the netconn (TCP, UDP or RAW) */
enum netconn_type type;
/** current state of the netconn */
enum netconn_state state;
/** the lwIP internal protocol control block */
union {
struct ip_pcb *ip;
struct tcp_pcb *tcp;
struct udp_pcb *udp;
struct raw_pcb *raw;
} pcb;
/** the last error this netconn had */
err_t last_err;
#if !LWIP_NETCONN_SEM_PER_THREAD
/** sem that is used to synchronously execute functions in the core context */
sys_sem_t op_completed;
#endif
/** mbox where received packets are stored until they are fetched
by the netconn application thread (can grow quite big) */
sys_mbox_t recvmbox;
#if LWIP_TCP
/** mbox where new connections are stored until processed
by the application thread */
sys_mbox_t acceptmbox;
#endif /* LWIP_TCP */
/** only used for socket layer */
#if LWIP_SOCKET
int socket;
#endif /* LWIP_SOCKET */
#if LWIP_SO_SNDTIMEO
/** timeout to wait for sending data (which means enqueueing data for sending
in internal buffers) in milliseconds */
s32_t send_timeout;
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVTIMEO
/** timeout in milliseconds to wait for new data to be received
(or connections to arrive for listening netconns) */
int recv_timeout;
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVBUF
/** maximum amount of bytes queued in recvmbox
not used for TCP: adjust TCP_WND instead! */
int recv_bufsize;
/** number of bytes currently in recvmbox to be received,
tested against recv_bufsize to limit bytes on recvmbox
for UDP and RAW, used for FIONREAD */
int recv_avail;
#endif /* LWIP_SO_RCVBUF */
#if LWIP_SO_LINGER
/** values <0 mean linger is disabled, values > 0 are seconds to linger */
s16_t linger;
#endif /* LWIP_SO_LINGER */
/** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
u8_t flags;
#if LWIP_TCP
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
this temporarily stores how much is already sent. */
size_t write_offset;
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
this temporarily stores the message.
Also used during connect and close. */
struct api_msg_msg *current_msg;
#endif /* LWIP_TCP */
/** A callback function that is informed about events for this netconn */
netconn_callback callback;
};
/** Register an Network connection event */
#define API_EVENT(c,e,l) if (c->callback) { \
(*c->callback)(c, e, l); \
}
/** Set conn->last_err to err but don't overwrite fatal errors */
#define NETCONN_SET_SAFE_ERR(conn, err) do { if ((conn) != NULL) { \
SYS_ARCH_DECL_PROTECT(netconn_set_safe_err_lev); \
SYS_ARCH_PROTECT(netconn_set_safe_err_lev); \
if (!ERR_IS_FATAL((conn)->last_err)) { \
(conn)->last_err = err; \
} \
SYS_ARCH_UNPROTECT(netconn_set_safe_err_lev); \
}} while(0);
/* Network connection functions: */
#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL)
#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c)
struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
netconn_callback callback);
err_t netconn_delete(struct netconn *conn);
/** Get the type of a netconn (as enum netconn_type). */
#define netconn_type(conn) (conn->type)
err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr,
u16_t *port, u8_t local);
#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0)
#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port);
err_t netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port);
err_t netconn_disconnect (struct netconn *conn);
err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
err_t netconn_accept(struct netconn *conn, struct netconn **new_conn);
err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf);
err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
void netconn_recved(struct netconn *conn, u32_t length);
err_t netconn_sendto(struct netconn *conn, struct netbuf *buf,
const ip_addr_t *addr, u16_t port);
err_t netconn_send(struct netconn *conn, struct netbuf *buf);
err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
u8_t apiflags, size_t *bytes_written);
#define netconn_write(conn, dataptr, size, apiflags) \
netconn_write_partly(conn, dataptr, size, apiflags, NULL)
err_t netconn_close(struct netconn *conn);
err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx);
#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
err_t netconn_join_leave_group(struct netconn *conn, const ip_addr_t *multiaddr,
const ip_addr_t *netif_addr, enum netconn_igmp join_or_leave);
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
#if LWIP_DNS
#if LWIP_IPV4 && LWIP_IPV6
err_t netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype);
#define netconn_gethostbyname(name, addr) netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_DEFAULT)
#else /* LWIP_IPV4 && LWIP_IPV6 */
err_t netconn_gethostbyname(const char *name, ip_addr_t *addr);
#define netconn_gethostbyname_addrtype(name, addr, dns_addrtype) netconn_gethostbyname(name, addr)
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#endif /* LWIP_DNS */
#define netconn_err(conn) ((conn)->last_err)
#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize)
/** Set the blocking status of netconn calls (@todo: write/send is missing) */
#define netconn_set_nonblocking(conn, val) do { if(val) { \
(conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \
} else { \
(conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0)
/** Get the blocking status of netconn calls (@todo: write/send is missing) */
#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0)
/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
#define netconn_set_noautorecved(conn, val) do { if(val) { \
(conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \
} else { \
(conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0)
/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0)
#if LWIP_IPV6
/** TCP: Set the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY) */
#define netconn_set_ipv6only(conn, val) do { if(val) { \
(conn)->flags |= NETCONN_FLAG_IPV6_V6ONLY; \
} else { \
(conn)->flags &= ~ NETCONN_FLAG_IPV6_V6ONLY; }} while(0)
/** TCP: Get the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY) */
#define netconn_get_ipv6only(conn) (((conn)->flags & NETCONN_FLAG_IPV6_V6ONLY) != 0)
#endif /* LWIP_IPV6 */
#if LWIP_SO_SNDTIMEO
/** Set the send timeout in milliseconds */
#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout))
/** Get the send timeout in milliseconds */
#define netconn_get_sendtimeout(conn) ((conn)->send_timeout)
#endif /* LWIP_SO_SNDTIMEO */
#if LWIP_SO_RCVTIMEO
/** Set the receive timeout in milliseconds */
#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout))
/** Get the receive timeout in milliseconds */
#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout)
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVBUF
/** Set the receive buffer in bytes */
#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize))
/** Get the receive buffer in bytes */
#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize)
#endif /* LWIP_SO_RCVBUF*/
#if LWIP_NETCONN_SEM_PER_THREAD
void netconn_thread_init(void);
void netconn_thread_cleanup(void);
#else /* LWIP_NETCONN_SEM_PER_THREAD */
#define netconn_thread_init()
#define netconn_thread_cleanup()
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_NETCONN || LWIP_SOCKET */
#endif /* LWIP_HDR_API_H */

View file

@ -1,238 +0,0 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_ARCH_H
#define LWIP_HDR_ARCH_H
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#include "arch/cc.h"
/** Temporary: define format string for size_t if not defined in cc.h */
#ifndef SZT_F
#define SZT_F U32_F
#endif /* SZT_F */
/** Temporary upgrade helper: define format string for u8_t as hex if not
defined in cc.h */
#ifndef X8_F
#define X8_F "02x"
#endif /* X8_F */
/** C++ const_cast<target_type>(val) equivalent to remove constness from a value (GCC -Wcast-qual) */
#ifndef LWIP_CONST_CAST
#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val))
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef PACK_STRUCT_BEGIN
#define PACK_STRUCT_BEGIN
#endif /* PACK_STRUCT_BEGIN */
#ifndef PACK_STRUCT_END
#define PACK_STRUCT_END
#endif /* PACK_STRUCT_END */
#ifndef PACK_STRUCT_STRUCT
#define PACK_STRUCT_STRUCT
#endif /* PACK_STRUCT_STRUCT */
#ifndef PACK_STRUCT_FIELD
#define PACK_STRUCT_FIELD(x) x
#endif /* PACK_STRUCT_FIELD */
/* Used for struct fields of u8_t,
* where some compilers warn that packing is not necessary */
#ifndef PACK_STRUCT_FLD_8
#define PACK_STRUCT_FLD_8(x) PACK_STRUCT_FIELD(x)
#endif /* PACK_STRUCT_FLD_8 */
/* Used for struct fields of that are packed structs themself,
* where some compilers warn that packing is not necessary */
#ifndef PACK_STRUCT_FLD_S
#define PACK_STRUCT_FLD_S(x) PACK_STRUCT_FIELD(x)
#endif /* PACK_STRUCT_FLD_S */
#ifndef LWIP_UNUSED_ARG
#define LWIP_UNUSED_ARG(x) (void)x
#endif /* LWIP_UNUSED_ARG */
#ifdef LWIP_PROVIDE_ERRNO
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#ifndef errno
extern int errno;
#endif
#endif /* LWIP_PROVIDE_ERRNO */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_ARCH_H */

View file

@ -1,124 +0,0 @@
/**
* @file
*
* AutoIP Automatic LinkLocal IP Configuration
*/
/*
*
* Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Dominik Spies <kontakt@dspies.de>
*
* This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
* with RFC 3927.
*
*
* Please coordinate changes and requests with Dominik Spies
* <kontakt@dspies.de>
*/
#ifndef LWIP_HDR_AUTOIP_H
#define LWIP_HDR_AUTOIP_H
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
#include "lwip/netif.h"
/* #include "lwip/udp.h" */
#include "netif/etharp.h"
#ifdef __cplusplus
extern "C" {
#endif
/* AutoIP Timing */
#define AUTOIP_TMR_INTERVAL 100
#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL)
/* RFC 3927 Constants */
#define PROBE_WAIT 1 /* second (initial random delay) */
#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */
#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */
#define PROBE_NUM 3 /* (number of probe packets) */
#define ANNOUNCE_NUM 2 /* (number of announcement packets) */
#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */
#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */
#define MAX_CONFLICTS LWIP_AUTOIP_MAX_CONFLICTS /* (max conflicts before rate limiting) */
#define RATE_LIMIT_INTERVAL LWIP_AUTOIP_RATE_LIMIT_INTERVAL /* seconds (delay between successive attempts) */
#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */
/* AutoIP client states */
#define AUTOIP_STATE_OFF 0
#define AUTOIP_STATE_PROBING 1
#define AUTOIP_STATE_ANNOUNCING 2
#define AUTOIP_STATE_BOUND 3
struct autoip
{
ip4_addr_t llipaddr; /* the currently selected, probed, announced or used LL IP-Address */
u8_t state; /* current AutoIP state machine state */
u8_t sent_num; /* sent number of probes or announces, dependent on state */
u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */
u8_t lastconflict; /* ticks until a conflict can be solved by defending */
u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */
};
#define autoip_init() /* Compatibility define, no init needed. */
/** Set a struct autoip allocated by the application to work with */
void autoip_set_struct(struct netif *netif, struct autoip *autoip);
/** Remove a struct autoip previously set to the netif using autoip_set_struct() */
#define autoip_remove_struct(netif) do { (netif)->autoip = NULL; } while (0)
/** Start AutoIP client */
err_t autoip_start(struct netif *netif);
/** Stop AutoIP client */
err_t autoip_stop(struct netif *netif);
/** Handles every incoming ARP Packet, called by etharp_arp_input */
void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */
void autoip_tmr(void);
/** Handle a possible change in the network configuration */
void autoip_network_changed(struct netif *netif);
/** check if AutoIP supplied netif->ip_addr */
u8_t autoip_supplied_address(struct netif *netif);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_IPV4 && LWIP_AUTOIP */
#endif /* LWIP_HDR_AUTOIP_H */

View file

@ -1,117 +0,0 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_DEBUG_H
#define LWIP_HDR_DEBUG_H
#include "lwip/arch.h"
#include "lwip/opt.h"
/** lower two bits indicate debug level
* - 0 all
* - 1 warning
* - 2 serious
* - 3 severe
*/
#define LWIP_DBG_LEVEL_ALL 0x00
#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */
#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */
#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */
#define LWIP_DBG_LEVEL_SEVERE 0x03
#define LWIP_DBG_MASK_LEVEL 0x03
/** flag for LWIP_DEBUGF to enable that debug message */
#define LWIP_DBG_ON 0x80U
/** flag for LWIP_DEBUGF to disable that debug message */
#define LWIP_DBG_OFF 0x00U
/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */
#define LWIP_DBG_TRACE 0x40U
/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */
#define LWIP_DBG_STATE 0x20U
/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */
#define LWIP_DBG_FRESH 0x10U
/** flag for LWIP_DEBUGF to halt after printing this debug message */
#define LWIP_DBG_HALT 0x08U
/**
* LWIP_NOASSERT: Disable LWIP_ASSERT checks.
* -- To disable assertions define LWIP_NOASSERT in arch/cc.h.
*/
#ifndef LWIP_NOASSERT
#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \
LWIP_PLATFORM_ASSERT(message); } while(0)
#ifndef LWIP_PLATFORM_ASSERT
#error "If you want to use LWIP_ASSERT, LWIP_PLATFORM_ASSERT(message) needs to be defined in your arch/cc.h"
#endif
#else /* LWIP_NOASSERT */
#define LWIP_ASSERT(message, assertion)
#endif /* LWIP_NOASSERT */
/** if "expression" isn't true, then print "message" and execute "handler" expression */
#ifndef LWIP_ERROR
#ifndef LWIP_NOASSERT
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message)
#elif defined LWIP_DEBUG
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message))
#else
#define LWIP_PLATFORM_ERROR(message)
#endif
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
LWIP_PLATFORM_ERROR(message); handler;}} while(0)
#endif /* LWIP_ERROR */
#ifdef LWIP_DEBUG
#ifndef LWIP_PLATFORM_DIAG
#error "If you want to use LWIP_DEBUG, LWIP_PLATFORM_DIAG(message) needs to be defined in your arch/cc.h"
#endif
/** print debug message only if debug message type is enabled...
* AND is of correct type AND is at least LWIP_DBG_LEVEL
*/
#define LWIP_DEBUGF(debug, message) do { \
if ( \
((debug) & LWIP_DBG_ON) && \
((debug) & LWIP_DBG_TYPES_ON) && \
((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
LWIP_PLATFORM_DIAG(message); \
if ((debug) & LWIP_DBG_HALT) { \
while(1); \
} \
} \
} while(0)
#else /* LWIP_DEBUG */
#define LWIP_DEBUGF(debug, message)
#endif /* LWIP_DEBUG */
#endif /* LWIP_HDR_DEBUG_H */

View file

@ -1,132 +0,0 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_DEF_H
#define LWIP_HDR_DEF_H
/* arch.h might define NULL already */
#include "lwip/arch.h"
#include "lwip/opt.h"
#if LWIP_PERF
#include "arch/perf.h"
#else /* LWIP_PERF */
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* LWIP_PERF */
#ifdef __cplusplus
extern "C" {
#endif
#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y))
#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y))
/* Get the number of entries in an array ('x' must NOT be a pointer!) */
#define LWIP_ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
#ifndef NULL
#define NULL ((void *)0)
#endif
/* Endianess-optimized shifting of two u8_t to create one u16_t */
#if BYTE_ORDER == LITTLE_ENDIAN
#define LWIP_MAKE_U16(a, b) ((a << 8) | b)
#else
#define LWIP_MAKE_U16(a, b) ((b << 8) | a)
#endif
#ifndef LWIP_PLATFORM_BYTESWAP
#define LWIP_PLATFORM_BYTESWAP 0
#endif
#ifndef LWIP_PREFIX_BYTEORDER_FUNCS
/* workaround for naming collisions on some platforms */
#ifdef htons
#undef htons
#endif /* htons */
#ifdef htonl
#undef htonl
#endif /* htonl */
#ifdef ntohs
#undef ntohs
#endif /* ntohs */
#ifdef ntohl
#undef ntohl
#endif /* ntohl */
#define htons(x) lwip_htons(x)
#define ntohs(x) lwip_ntohs(x)
#define htonl(x) lwip_htonl(x)
#define ntohl(x) lwip_ntohl(x)
#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */
#if BYTE_ORDER == BIG_ENDIAN
#define lwip_htons(x) (x)
#define lwip_ntohs(x) (x)
#define lwip_htonl(x) (x)
#define lwip_ntohl(x) (x)
#define PP_HTONS(x) (x)
#define PP_NTOHS(x) (x)
#define PP_HTONL(x) (x)
#define PP_NTOHL(x) (x)
#else /* BYTE_ORDER != BIG_ENDIAN */
#if LWIP_PLATFORM_BYTESWAP
#define lwip_htons(x) LWIP_PLATFORM_HTONS(x)
#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x)
#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x)
#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x)
#else /* LWIP_PLATFORM_BYTESWAP */
u16_t lwip_htons(u16_t x);
u16_t lwip_ntohs(u16_t x);
u32_t lwip_htonl(u32_t x);
u32_t lwip_ntohl(u32_t x);
#endif /* LWIP_PLATFORM_BYTESWAP */
/* These macros should be calculated by the preprocessor and are used
with compile-time constants only (so that there is no little-endian
overhead at runtime). */
#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & 0xff) << 24) | \
(((x) & 0xff00) << 8) | \
(((x) & 0xff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#endif /* BYTE_ORDER == BIG_ENDIAN */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_DEF_H */

View file

@ -1,314 +0,0 @@
/*
* Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
* Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Leon Woestenberg <leon.woestenberg@gmx.net>
*
*/
#ifndef LWIP_HDR_DHCP_H
#define LWIP_HDR_DHCP_H
#include "lwip/opt.h"
#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/netif.h"
#include "lwip/udp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** period (in seconds) of the application calling dhcp_coarse_tmr() */
#define DHCP_COARSE_TIMER_SECS 1
/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */
#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL)
/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
#define DHCP_FINE_TIMER_MSECS 500
#define DHCP_CHADDR_LEN 16U
#define DHCP_SNAME_LEN 64U
#define DHCP_FILE_LEN 128U
struct dhcp
{
/** transaction identifier of last sent request */
u32_t xid;
/** incoming msg */
struct dhcp_msg *msg_in;
/** track PCB allocation state */
u8_t pcb_allocated;
/** current DHCP state machine state */
u8_t state;
/** retries of current request */
u8_t tries;
#if LWIP_DHCP_AUTOIP_COOP
u8_t autoip_coop_state;
#endif
u8_t subnet_mask_given;
struct pbuf *p_out; /* pbuf of outcoming msg */
struct dhcp_msg *msg_out; /* outgoing msg */
u16_t options_out_len; /* outgoing msg options length */
u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
u32_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
u32_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
u32_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */
u32_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */
u32_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */
u32_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */
ip_addr_t server_ip_addr; /* dhcp server address that offered this lease (ip_addr_t because passed to UDP) */
ip4_addr_t offered_ip_addr;
ip4_addr_t offered_sn_mask;
ip4_addr_t offered_gw_addr;
u32_t offered_t0_lease; /* lease period (in seconds) */
u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
u32_t offered_t2_rebind; /* recommended rebind time (usually 87.5 of lease period) */
#if LWIP_DHCP_BOOTP_FILE
ip_addr_t offered_si_addr;
char boot_file_name[DHCP_FILE_LEN];
#endif /* LWIP_DHCP_BOOTPFILE */
/* Espressif add start. */
#ifdef ESP_LWIP
void (*cb)(struct netif*); /* callback for dhcp, add a parameter to show dhcp status if needed */
#else
void (*cb)(void); /* callback for dhcp, add a parameter to show dhcp status if needed */
#endif
/* Espressif add end. */
};
/* MUST be compiled with "pack structs" or equivalent! */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** minimum set of fields of any DHCP message */
struct dhcp_msg
{
PACK_STRUCT_FLD_8(u8_t op);
PACK_STRUCT_FLD_8(u8_t htype);
PACK_STRUCT_FLD_8(u8_t hlen);
PACK_STRUCT_FLD_8(u8_t hops);
PACK_STRUCT_FIELD(u32_t xid);
PACK_STRUCT_FIELD(u16_t secs);
PACK_STRUCT_FIELD(u16_t flags);
PACK_STRUCT_FLD_S(ip4_addr_p_t ciaddr);
PACK_STRUCT_FLD_S(ip4_addr_p_t yiaddr);
PACK_STRUCT_FLD_S(ip4_addr_p_t siaddr);
PACK_STRUCT_FLD_S(ip4_addr_p_t giaddr);
PACK_STRUCT_FLD_8(u8_t chaddr[DHCP_CHADDR_LEN]);
PACK_STRUCT_FLD_8(u8_t sname[DHCP_SNAME_LEN]);
PACK_STRUCT_FLD_8(u8_t file[DHCP_FILE_LEN]);
PACK_STRUCT_FIELD(u32_t cookie);
#define DHCP_MIN_OPTIONS_LEN 68U
/** make sure user does not configure this too small */
#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
# undef DHCP_OPTIONS_LEN
#endif
/** allow this to be configured in lwipopts.h, but not too small */
#if (!defined(DHCP_OPTIONS_LEN))
/** set this to be sufficient for your options in outgoing DHCP msgs */
# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
#endif
PACK_STRUCT_FLD_8(u8_t options[DHCP_OPTIONS_LEN]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp);
/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */
#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0)
void dhcp_cleanup(struct netif *netif);
/* Espressif add start. */
/** set callback for DHCP */
#ifdef ESP_LWIP
void dhcp_set_cb(struct netif *netif, void (*cb)(struct netif*));
#else
void dhcp_set_cb(struct netif *netif, void (*cb)(void));
#endif
/* Espressif add end. */
/** start DHCP configuration */
err_t dhcp_start(struct netif *netif);
/** enforce early lease renewal (not needed normally)*/
err_t dhcp_renew(struct netif *netif);
/** release the DHCP lease, usually called before dhcp_stop()*/
err_t dhcp_release(struct netif *netif);
/** stop DHCP configuration */
void dhcp_stop(struct netif *netif);
/** inform server of our manual IP address */
void dhcp_inform(struct netif *netif);
/** Handle a possible change in the network configuration */
void dhcp_network_changed(struct netif *netif);
/** if enabled, check whether the offered IP address is not in use, using ARP */
#if DHCP_DOES_ARP_CHECK
void dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr);
#endif
/** check if DHCP supplied netif->ip_addr */
u8_t dhcp_supplied_address(struct netif *netif);
/** to be called every minute */
void dhcp_coarse_tmr(void);
/** to be called every half second */
void dhcp_fine_tmr(void);
/** DHCP message item offsets and length */
#define DHCP_OP_OFS 0
#define DHCP_HTYPE_OFS 1
#define DHCP_HLEN_OFS 2
#define DHCP_HOPS_OFS 3
#define DHCP_XID_OFS 4
#define DHCP_SECS_OFS 8
#define DHCP_FLAGS_OFS 10
#define DHCP_CIADDR_OFS 12
#define DHCP_YIADDR_OFS 16
#define DHCP_SIADDR_OFS 20
#define DHCP_GIADDR_OFS 24
#define DHCP_CHADDR_OFS 28
#define DHCP_SNAME_OFS 44
#define DHCP_FILE_OFS 108
#define DHCP_MSG_LEN 236
#define DHCP_COOKIE_OFS DHCP_MSG_LEN
#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4)
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_PORT 67
/** DHCP client states */
#define DHCP_STATE_OFF 0
#define DHCP_STATE_REQUESTING 1
#define DHCP_STATE_INIT 2
#define DHCP_STATE_REBOOTING 3
#define DHCP_STATE_REBINDING 4
#define DHCP_STATE_RENEWING 5
#define DHCP_STATE_SELECTING 6
#define DHCP_STATE_INFORMING 7
#define DHCP_STATE_CHECKING 8
/** not yet implemented #define DHCP_STATE_PERMANENT 9 */
#define DHCP_STATE_BOUND 10
/** not yet implemented #define DHCP_STATE_RELEASING 11 */
#define DHCP_STATE_BACKING_OFF 12
/** AUTOIP cooperation flags */
#define DHCP_AUTOIP_COOP_STATE_OFF 0
#define DHCP_AUTOIP_COOP_STATE_ON 1
#define DHCP_BOOTREQUEST 1
#define DHCP_BOOTREPLY 2
/** DHCP message types */
#define DHCP_DISCOVER 1
#define DHCP_OFFER 2
#define DHCP_REQUEST 3
#define DHCP_DECLINE 4
#define DHCP_ACK 5
#define DHCP_NAK 6
#define DHCP_RELEASE 7
#define DHCP_INFORM 8
/** DHCP hardware type, currently only ethernet is supported */
#define DHCP_HTYPE_ETH 1
#define DHCP_MAGIC_COOKIE 0x63825363UL
/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */
/** BootP options */
#define DHCP_OPTION_PAD 0
#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
#define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6
#define DHCP_OPTION_HOSTNAME 12
#define DHCP_OPTION_IP_TTL 23
#define DHCP_OPTION_MTU 26
#define DHCP_OPTION_BROADCAST 28
#define DHCP_OPTION_TCP_TTL 37
#define DHCP_OPTION_NTP 42
#define DHCP_OPTION_END 255
#if ESP_LWIP
/**add options for support more router by liuHan**/
#define DHCP_OPTION_DOMAIN_NAME 15
#define DHCP_OPTION_PRD 31
#define DHCP_OPTION_STATIC_ROUTER 33
#define DHCP_OPTION_VSN 43
#define DHCP_OPTION_NB_TINS 44
#define DHCP_OPTION_NB_TINT 46
#define DHCP_OPTION_NB_TIS 47
#define DHCP_OPTION_CLASSLESS_STATIC_ROUTER 121
#endif
/** DHCP options */
#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */
#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */
#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */
#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */
#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
#define DHCP_OPTION_T1 58 /* T1 renewal time */
#define DHCP_OPTION_T2 59 /* T2 rebinding time */
#define DHCP_OPTION_US 60
#define DHCP_OPTION_CLIENT_ID 61
#define DHCP_OPTION_TFTP_SERVERNAME 66
#define DHCP_OPTION_BOOTFILE 67
/** possible combinations of overloading the file and sname fields with options */
#define DHCP_OVERLOAD_NONE 0
#define DHCP_OVERLOAD_FILE 1
#define DHCP_OVERLOAD_SNAME 2
#define DHCP_OVERLOAD_SNAME_FILE 3
#if LWIP_DHCP_GET_NTP_SRV
/** This function must exist, in other to add offered NTP servers to
* the NTP (or SNTP) engine.
* See LWIP_DHCP_MAX_NTP_SERVERS */
extern void dhcp_set_ntp_servers(u8_t num_ntp_servers, const ip4_addr_t* ntp_server_addrs);
#endif /* LWIP_DHCP_GET_NTP_SRV */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_DHCP */
#endif /*LWIP_HDR_DHCP_H*/

View file

@ -1,58 +0,0 @@
/**
* @file
*
* IPv6 address autoconfiguration as per RFC 4862.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
* IPv6 address autoconfiguration as per RFC 4862.
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#ifndef LWIP_HDR_IP6_DHCP6_H
#define LWIP_HDR_IP6_DHCP6_H
#include "lwip/opt.h"
#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */
struct dhcp6
{
/*TODO: implement DHCP6*/
};
#endif /* LWIP_IPV6_DHCP6 */
#endif /* LWIP_HDR_IP6_DHCP6_H */

View file

@ -1,119 +0,0 @@
/**
* lwip DNS resolver header file.
* Author: Jim Pettinato
* April 2007
* ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LWIP_HDR_DNS_H
#define LWIP_HDR_DNS_H
#include "lwip/opt.h"
#if ESP_DNS
#include "lwip/err.h"
#endif
#if LWIP_DNS
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
/** DNS timer period */
#define DNS_TMR_INTERVAL 1000
/* DNS resolve types: */
#define LWIP_DNS_ADDRTYPE_IPV4 0
#define LWIP_DNS_ADDRTYPE_IPV6 1
#define LWIP_DNS_ADDRTYPE_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */
#define LWIP_DNS_ADDRTYPE_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */
#if LWIP_IPV4 && LWIP_IPV6
#ifndef LWIP_DNS_ADDRTYPE_DEFAULT
#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV4_IPV6
#endif
#elif defined(LWIP_IPV4)
#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV4
#else
#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV6
#endif
#if DNS_LOCAL_HOSTLIST
/** struct used for local host-list */
struct local_hostlist_entry {
/** static hostname */
const char *name;
/** static host address in network byteorder */
ip_addr_t addr;
struct local_hostlist_entry *next;
};
#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC
#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN
#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH
#endif
#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1))
#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
#endif /* DNS_LOCAL_HOSTLIST */
/** Callback which is invoked when a hostname is found.
* A function of this type must be implemented by the application using the DNS resolver.
* @param name pointer to the name that was looked up.
* @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname,
* or NULL if the name could not be found (or on any other error).
* @param callback_arg a user-specified callback argument passed to dns_gethostbyname
*/
typedef void (*dns_found_callback)(const char *name, const ip_addr_t *ipaddr, void *callback_arg);
void dns_init(void);
void dns_tmr(void);
void dns_setserver(u8_t numdns, const ip_addr_t *dnsserver);
void dns_clear_servers(bool keep_fallback);
ip_addr_t dns_getserver(u8_t numdns);
err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr,
dns_found_callback found, void *callback_arg);
err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr,
dns_found_callback found, void *callback_arg,
u8_t dns_addrtype);
#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC
int dns_local_removehost(const char *hostname, const ip_addr_t *addr);
err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr);
#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_DNS */
#endif /* LWIP_HDR_DNS_H */

View file

@ -1,95 +0,0 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_ERR_H
#define LWIP_HDR_ERR_H
#include "lwip/opt.h"
#include "lwip/arch.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Define LWIP_ERR_T in cc.h if you want to use
* a different type for your platform (must be signed). */
#ifdef LWIP_ERR_T
typedef LWIP_ERR_T err_t;
#else /* LWIP_ERR_T */
typedef s8_t err_t;
#endif /* LWIP_ERR_T*/
/* Definitions for error constants. */
#define ERR_OK 0 /* No error, everything OK. */
#define ERR_MEM -1 /* Out of memory error. */
#define ERR_BUF -2 /* Buffer error. */
#define ERR_TIMEOUT -3 /* Timeout. */
#define ERR_RTE -4 /* Routing problem. */
#define ERR_INPROGRESS -5 /* Operation in progress */
#define ERR_VAL -6 /* Illegal value. */
#define ERR_WOULDBLOCK -7 /* Operation would block. */
#define ERR_USE -8 /* Address in use. */
#if ESP_LWIP
#define ERR_ALREADY -9 /* Already connected. */
#define ERR_ISCONN -10 /* Conn already established.*/
#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN)
#define ERR_ABRT -11 /* Connection aborted. */
#define ERR_RST -12 /* Connection reset. */
#define ERR_CLSD -13 /* Connection closed. */
#define ERR_CONN -14 /* Not connected. */
#define ERR_ARG -15 /* Illegal argument. */
#define ERR_IF -16 /* Low-level netif error */
#else
#define ERR_ALREADY -9 /* Already connecting. */
#define ERR_ISCONN -10 /* Conn already established.*/
#define ERR_CONN -11 /* Not connected. */
#define ERR_IF -12 /* Low-level netif error */
#define ERR_IS_FATAL(e) ((e) <= ERR_ABRT)
#define ERR_ABRT -13 /* Connection aborted. */
#define ERR_RST -14 /* Connection reset. */
#define ERR_CLSD -15 /* Connection closed. */
#define ERR_ARG -16 /* Illegal argument. */
#endif
#ifdef LWIP_DEBUG
extern const char *lwip_strerr(err_t err);
#else
#define lwip_strerr(x) ""
#endif /* LWIP_DEBUG */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_ERR_H */

View file

@ -1,68 +0,0 @@
/**
* @file
*
* Ethernet output for IPv6. Uses ND tables for link-layer addressing.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#ifndef LWIP_HDR_ETHIP6_H
#define LWIP_HDR_ETHIP6_H
#include "lwip/opt.h"
#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */
#include "lwip/pbuf.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
err_t ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_IPV6 && LWIP_ETHERNET */
#endif /* LWIP_HDR_ETHIP6_H */

View file

@ -1,137 +0,0 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_ICMP_H
#define LWIP_HDR_ICMP_H
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#if LWIP_IPV6 && LWIP_ICMP6
#include "lwip/icmp6.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define ICMP_ER 0 /* echo reply */
#define ICMP_DUR 3 /* destination unreachable */
#define ICMP_SQ 4 /* source quench */
#define ICMP_RD 5 /* redirect */
#define ICMP_ECHO 8 /* echo */
#define ICMP_TE 11 /* time exceeded */
#define ICMP_PP 12 /* parameter problem */
#define ICMP_TS 13 /* timestamp */
#define ICMP_TSR 14 /* timestamp reply */
#define ICMP_IRQ 15 /* information request */
#define ICMP_IR 16 /* information reply */
#define ICMP_AM 17 /* address mask request */
#define ICMP_AMR 18 /* address mask reply */
enum icmp_dur_type {
ICMP_DUR_NET = 0, /* net unreachable */
ICMP_DUR_HOST = 1, /* host unreachable */
ICMP_DUR_PROTO = 2, /* protocol unreachable */
ICMP_DUR_PORT = 3, /* port unreachable */
ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
ICMP_DUR_SR = 5 /* source route failed */
};
enum icmp_te_type {
ICMP_TE_TTL = 0, /* time to live exceeded in transit */
ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
};
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
/** This is the standard ICMP header only that the u32_t data
* is split to two u16_t like ICMP echo needs it.
* This header is also used for other ICMP types that do not
* use the data part.
*/
PACK_STRUCT_BEGIN
struct icmp_echo_hdr {
PACK_STRUCT_FLD_8(u8_t type);
PACK_STRUCT_FLD_8(u8_t code);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u16_t id);
PACK_STRUCT_FIELD(u16_t seqno);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define ICMPH_TYPE(hdr) ((hdr)->type)
#define ICMPH_CODE(hdr) ((hdr)->code)
/** Combines type and code to an u16_t */
#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t))
#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c))
#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
void icmp_input(struct pbuf *p, struct netif *inp);
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
#endif /* LWIP_IPV4 && LWIP_ICMP */
#if LWIP_IPV4 && LWIP_IPV6
#if LWIP_ICMP && LWIP_ICMP6
#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \
icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \
icmp_dest_unreach(pbuf, ICMP_DUR_PORT))
#elif LWIP_ICMP
#define icmp_port_unreach(isipv6, pbuf) do{ if(!(isipv6)) { icmp_dest_unreach(pbuf, ICMP_DUR_PORT);}}while(0)
#elif LWIP_ICMP6
#define icmp_port_unreach(isipv6, pbuf) do{ if(isipv6) { icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT);}}while(0)
#else
#define icmp_port_unreach(isipv6, pbuf)
#endif
#elif LWIP_IPV6 && LWIP_ICMP6
#define icmp_port_unreach(isipv6, pbuf) icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT)
#elif LWIP_IPV4 && LWIP_ICMP
#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT)
#else /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) */
#define icmp_port_unreach(isipv6, pbuf)
#endif /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) LWIP_IPV4*/
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_ICMP_H */

View file

@ -1,152 +0,0 @@
/**
* @file
*
* IPv6 version of ICMP, as per RFC 4443.
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
*/
#ifndef LWIP_HDR_ICMP6_H
#define LWIP_HDR_ICMP6_H
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/ip6_addr.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
enum icmp6_type {
ICMP6_TYPE_DUR = 1, /* Destination unreachable */
ICMP6_TYPE_PTB = 2, /* Packet too big */
ICMP6_TYPE_TE = 3, /* Time exceeded */
ICMP6_TYPE_PP = 4, /* Parameter problem */
ICMP6_TYPE_PE1 = 100, /* Private experimentation */
ICMP6_TYPE_PE2 = 101, /* Private experimentation */
ICMP6_TYPE_RSV_ERR = 127, /* Reserved for expansion of error messages */
ICMP6_TYPE_EREQ = 128, /* Echo request */
ICMP6_TYPE_EREP = 129, /* Echo reply */
ICMP6_TYPE_MLQ = 130, /* Multicast listener query */
ICMP6_TYPE_MLR = 131, /* Multicast listener report */
ICMP6_TYPE_MLD = 132, /* Multicast listener done */
ICMP6_TYPE_RS = 133, /* Router solicitation */
ICMP6_TYPE_RA = 134, /* Router advertisement */
ICMP6_TYPE_NS = 135, /* Neighbor solicitation */
ICMP6_TYPE_NA = 136, /* Neighbor advertisement */
ICMP6_TYPE_RD = 137, /* Redirect */
ICMP6_TYPE_MRA = 151, /* Multicast router advertisement */
ICMP6_TYPE_MRS = 152, /* Multicast router solicitation */
ICMP6_TYPE_MRT = 153, /* Multicast router termination */
ICMP6_TYPE_PE3 = 200, /* Private experimentation */
ICMP6_TYPE_PE4 = 201, /* Private experimentation */
ICMP6_TYPE_RSV_INF = 255 /* Reserved for expansion of informational messages */
};
enum icmp6_dur_code {
ICMP6_DUR_NO_ROUTE = 0, /* No route to destination */
ICMP6_DUR_PROHIBITED = 1, /* Communication with destination administratively prohibited */
ICMP6_DUR_SCOPE = 2, /* Beyond scope of source address */
ICMP6_DUR_ADDRESS = 3, /* Address unreachable */
ICMP6_DUR_PORT = 4, /* Port unreachable */
ICMP6_DUR_POLICY = 5, /* Source address failed ingress/egress policy */
ICMP6_DUR_REJECT_ROUTE = 6 /* Reject route to destination */
};
enum icmp6_te_code {
ICMP6_TE_HL = 0, /* Hop limit exceeded in transit */
ICMP6_TE_FRAG = 1 /* Fragment reassembly time exceeded */
};
enum icmp6_pp_code {
ICMP6_PP_FIELD = 0, /* Erroneous header field encountered */
ICMP6_PP_HEADER = 1, /* Unrecognized next header type encountered */
ICMP6_PP_OPTION = 2 /* Unrecognized IPv6 option encountered */
};
/** This is the standard ICMP6 header. */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct icmp6_hdr {
PACK_STRUCT_FLD_8(u8_t type);
PACK_STRUCT_FLD_8(u8_t code);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u32_t data);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/** This is the ICMP6 header adapted for echo req/resp. */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct icmp6_echo_hdr {
PACK_STRUCT_FLD_8(u8_t type);
PACK_STRUCT_FLD_8(u8_t code);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u16_t id);
PACK_STRUCT_FIELD(u16_t seqno);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
void icmp6_input(struct pbuf *p, struct netif *inp);
void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c);
void icmp6_packet_too_big(struct pbuf *p, u32_t mtu);
void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c);
void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer);
#endif /* LWIP_ICMP6 && LWIP_IPV6 */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_ICMP6_H */

View file

@ -1,108 +0,0 @@
/*
* Copyright (c) 2002 CITEL Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is a contribution to the lwIP TCP/IP stack.
* The Swedish Institute of Computer Science and Adam Dunkels
* are specifically granted permission to redistribute this
* source code.
*/
#ifndef LWIP_HDR_IGMP_H
#define LWIP_HDR_IGMP_H
#include "lwip/opt.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
#ifdef __cplusplus
extern "C" {
#endif
/* IGMP timer */
#define IGMP_TMR_INTERVAL 100 /* Milliseconds */
#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL)
#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL)
/* MAC Filter Actions, these are passed to a netif's
* igmp_mac_filter callback function. */
#define IGMP_DEL_MAC_FILTER 0
#define IGMP_ADD_MAC_FILTER 1
/**
* igmp group structure - there is
* a list of groups for each interface
* these should really be linked from the interface, but
* if we keep them separate we will not affect the lwip original code
* too much
*
* There will be a group for the all systems group address but this
* will not run the state machine as it is used to kick off reports
* from all the other groups
*/
struct igmp_group {
/** next link */
struct igmp_group *next;
/** interface on which the group is active */
struct netif *netif;
/** multicast address */
ip4_addr_t group_address;
/** signifies we were the last person to report */
u8_t last_reporter_flag;
/** current state of the group */
u8_t group_state;
/** timer for reporting, negative is OFF */
u16_t timer;
/** counter of simultaneous uses */
u8_t use;
};
/* Prototypes */
void igmp_init(void);
err_t igmp_start(struct netif *netif);
err_t igmp_stop(struct netif *netif);
void igmp_report_groups(struct netif *netif);
struct igmp_group *igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr);
void igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest);
err_t igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr);
err_t igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr);
err_t igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr);
err_t igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr);
void igmp_tmr(void);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_IPV4 && LWIP_IGMP */
#endif /* LWIP_HDR_IGMP_H */

Some files were not shown because too many files have changed in this diff Show more