first submission

This commit is contained in:
qiyongshuang
2023-02-01 14:19:13 +08:00
parent d534aad004
commit b79c6ac80d
3711 changed files with 745432 additions and 2 deletions
@@ -0,0 +1,39 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("backtrace") {
sources = [ "los_backtrace.c" ]
include_dirs = [
"../../kernel/include",
"../../kernel/arch/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,416 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "los_backtrace.h"
#include "los_task.h"
#include "los_debug.h"
#if (LOSCFG_BACKTRACE_TYPE != 0)
#if (LOSCFG_BACKTRACE_TYPE == 1)
#define OS_BACKTRACE_START 2
/* Thumb instruction, so the pc must be an odd number */
#define OS_IS_THUMB_INSTRUCTION(pc) ((pc & 0x1) == 1)
/* BL or BLX instruction flag. */
#define OS_BL_INS_MASK 0xF800
#define OS_BL_INS_HIGH 0xF800
#define OS_BL_INS_LOW 0xF000
#define OS_BLX_INX_MASK 0xFF00
#define OS_BLX_INX 0x4700
#if defined(__ICCARM__) || defined(__CC_ARM)
STATIC INLINE UINTPTR HalSpGet(VOID)
{
UINTPTR sp;
__asm("mov %0, sp" : "=r" (sp));
return sp;
}
STATIC INLINE UINTPTR HalPspGet(VOID)
{
UINTPTR psp;
__asm("mrs %0, psp" : "=r" (psp));
return psp;
}
STATIC INLINE UINTPTR HalMspGet(VOID)
{
UINTPTR msp;
__asm("mrs %0, msp" : "=r" (msp));
return msp;
}
#elif defined(__CLANG_ARM) || defined(__GNUC__)
STATIC INLINE UINTPTR HalSpGet(VOID)
{
UINTPTR sp;
__asm volatile("mov %0, sp" : "=r" (sp));
return sp;
}
STATIC INLINE UINTPTR HalPspGet(VOID)
{
UINTPTR psp;
__asm volatile("mrs %0, psp" : "=r" (psp));
return psp;
}
STATIC INLINE UINTPTR HalMspGet(VOID)
{
UINTPTR msp;
__asm volatile("mrs %0, msp" : "=r" (msp));
return msp;
}
#else
#error Unknown compiler.
#endif
STATIC INLINE BOOL OsInsIsBlOrBlx(UINTPTR addr)
{
UINT16 ins1 = *((UINT16 *)addr);
UINT16 ins2 = *((UINT16 *)(addr + 2)); /* 2: Thumb instruction is two bytes. */
if (((ins2 & OS_BL_INS_MASK) == OS_BL_INS_HIGH) &&
((ins1 & OS_BL_INS_MASK) == OS_BL_INS_LOW)) {
return TRUE;
} else if ((ins2 & OS_BLX_INX_MASK) == OS_BLX_INX) {
return TRUE;
} else {
return FALSE;
}
}
STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINTPTR SP)
{
if (SP != 0) {
*stackStart = SP;
if ((SP >= CSTACK_START_ADDR) && (SP < CSTACK_END_ADDR)) {
*stackEnd = CSTACK_END_ADDR;
} else {
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((SP < (UINTPTR)taskCB->topOfStack) || (SP >= *stackEnd)) {
PRINT_ERR("msp statck [0x%x, 0x%x], cur task stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, (UINTPTR)taskCB->topOfStack, *stackEnd, SP);
return LOS_NOK;
}
}
} else {
if (HalSpGet() != HalPspGet()) {
*stackStart = HalMspGet();
*stackEnd = CSTACK_END_ADDR;
if ((*stackStart < CSTACK_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) {
PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, *stackStart);
return LOS_NOK;
}
PRINTK("msp, start = %x, end = %x\n", *stackStart, *stackEnd);
} else {
*stackStart = HalPspGet();
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((*stackStart < (UINTPTR)taskCB->topOfStack) || (*stackStart >= *stackEnd)) {
PRINT_ERR("psp stack [0x%x, 0x%x], cur sp(0x%x) is overflow, cur task id is %d!\n",
taskCB->topOfStack, *stackEnd, *stackStart, taskID);
return LOS_NOK;
}
PRINTK("psp, start = %x, end = %x\n", *stackStart, *stackEnd);
}
}
return LOS_OK;
}
STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
{
UINTPTR pc;
BOOL ret;
/* The stack space pointed to by the current SP may store the LR,
so need decrease a word to PC. */
pc = *((UINTPTR *)sp) - sizeof(UINTPTR);
if (!OS_IS_THUMB_INSTRUCTION(pc)) {
return 0;
}
/* PC in thumb mode is an odd number, fix the PC address by decreasing one byte. */
pc = *((UINTPTR *)sp) - 1;
ret = OsStackDataIsCodeAddr(pc);
if (ret == FALSE) {
return 0;
}
ret = OsInsIsBlOrBlx(pc - sizeof(UINTPTR));
if (ret == FALSE) {
return 0;
}
return pc;
}
#elif (LOSCFG_BACKTRACE_TYPE == 2)
STATIC INLINE BOOL OsBackTraceFpCheck(UINT32 value);
#define OS_BACKTRACE_START 1
#define OS_RA_OFFSET 4
#define OS_FP_OFFSET 8
#define OS_FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0)
#define OS_FP_CHECK(value) (((UINT32)(value) != FP_INIT_VALUE) && OS_FP_ALIGN(value))
STATIC INLINE UINTPTR OsFpGet(VOID)
{
UINTPTR fp = 0;
__asm volatile("mv %0, s0" : "=r"(fp));
dsb();
return fp;
}
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
{
UNUSED(SP);
UINT32 backFp = OsFpGet();
UINT32 tmpFp;
UINT32 backRa;
UINT32 count = 0;
UINT32 index = 0;
if (LR == NULL) {
return;
}
while (OS_FP_CHECK(backFp)) {
tmpFp = backFp;
backRa = *((UINT32 *)(UINTPTR)(tmpFp - OS_RA_OFFSET));
backFp = *((UINT32 *)(UINTPTR)(tmpFp - OS_FP_OFFSET));
if (index++ < jumpCount) {
continue;
}
LR[count] = backRa;
count++;
if ((count == LRSize) || (backFp == tmpFp) ||
(!OsStackDataIsCodeAddr(backRa))) {
break;
}
}
if (count < LRSize) {
LR[count] = 0;
}
}
#elif (LOSCFG_BACKTRACE_TYPE == 3)
#define OS_BACKTRACE_START 1
#define OS_JALX_INS_MASK 0x7F
#define OS_JAL_INS_LOW 0x6F
#define OS_JAL_16_INS_MASK 0x2001
#define OS_JALR_INS_LOW 0x67
#define OS_JALR_16_INS_MASK 0x9002
#define OS_JR_16_INS_MASK 0x8002
#define OS_J_16_INS_MASK 0xA001
STATIC INLINE BOOL OsInsIsJump(UINTPTR addr)
{
UINT16 ins1 = *((UINT16 *)addr);
UINT16 ins2 = *((UINT16 *)(addr + 2));
/* Jal ins */
if (((ins1 & OS_JALX_INS_MASK) == OS_JAL_INS_LOW) ||
((ins1 & OS_JAL_16_INS_MASK) == OS_JAL_16_INS_MASK) ||
((ins2 & OS_JAL_16_INS_MASK) == OS_JAL_16_INS_MASK)) {
return TRUE;
}
/* Jalr ins */
if (((ins1 & OS_JALX_INS_MASK) == OS_JALR_INS_LOW) ||
((ins1 & OS_JALR_16_INS_MASK) == OS_JALR_16_INS_MASK) ||
((ins2 & OS_JALR_16_INS_MASK) == OS_JALR_16_INS_MASK)) {
return TRUE;
}
/* Jr ins */
if (((ins1 & OS_JR_16_INS_MASK) == OS_JR_16_INS_MASK) ||
((ins2 & OS_JR_16_INS_MASK) == OS_JR_16_INS_MASK)) {
return TRUE;
}
/* J ins */
if (((ins1 & OS_J_16_INS_MASK) == OS_J_16_INS_MASK) ||
((ins2 & OS_J_16_INS_MASK) == OS_J_16_INS_MASK)) {
return TRUE;
}
return FALSE;
}
STATIC INLINE UINTPTR OsSpGet(VOID)
{
UINTPTR sp = 0;
__asm volatile("mv %0, sp" : "=r"(sp));
dsb();
return sp;
}
STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINTPTR SP)
{
if (SP != 0) {
*stackStart = SP;
if ((SP >= CSTACK_START_ADDR) && (SP < CSTACK_END_ADDR)) {
*stackEnd = CSTACK_END_ADDR;
} else {
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((SP < (UINTPTR)taskCB->topOfStack) || (SP >= *stackEnd)) {
PRINT_ERR("msp statck [0x%x, 0x%x], cur task stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, (UINTPTR)taskCB->topOfStack, *stackEnd, SP);
return LOS_NOK;
}
}
} else {
if (!LOS_TaskIsRunning()) {
*stackStart = OsSpGet();
*stackEnd = CSTACK_END_ADDR;
if ((*stackStart < CSTACK_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) {
PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, *stackStart);
return LOS_NOK;
}
} else {
*stackStart = OsSpGet();
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((*stackStart < (UINTPTR)taskCB->topOfStack) || (*stackStart >= *stackEnd)) {
PRINT_ERR("psp stack [0x%x, 0x%x], cur sp(0x%x) is overflow, cur task id is %d!\n",
taskCB->topOfStack, *stackEnd, *stackStart, taskID);
return LOS_NOK;
}
}
}
return LOS_OK;
}
STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
{
UINTPTR pc;
BOOL ret;
pc = *((UINTPTR *)sp);
ret = OsStackDataIsCodeAddr(pc);
if (ret == FALSE) {
return 0;
}
ret = OsInsIsJump(pc - sizeof(UINTPTR));
if (ret == FALSE) {
return 0;
}
return pc;
}
#else
#error Unknown backtrace type.
#endif
#if (LOSCFG_BACKTRACE_TYPE == 1) || (LOSCFG_BACKTRACE_TYPE == 3)
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
{
if (LR == NULL) {
return;
}
UINTPTR stackStart;
UINTPTR stackEnd;
UINT32 count = 0;
UINT32 index = 0;
UINTPTR sp;
UINTPTR pc;
UINT32 ret;
ret = OsStackAddrGet(&stackStart, &stackEnd, SP);
if (ret != LOS_OK) {
return;
}
/* Traverse the stack space and find the LR address. */
for (sp = stackStart; sp < stackEnd; sp += sizeof(UINTPTR)) {
pc = OsAddrIsValid(sp);
if ((pc != 0) && (count < LRSize)) {
if (index++ < jumpCount) {
continue;
}
LR[count] = pc;
count++;
if (count == LRSize) {
break;
}
}
}
if (count < LRSize) {
LR[count] = 0;
}
}
#endif
VOID LOS_BackTrace(VOID)
{
UINTPTR LR[BACKTRACE_MAX_DEPTH] = {0};
UINT32 index;
LOS_RecordLR(LR, BACKTRACE_MAX_DEPTH, OS_BACKTRACE_START, 0);
if (LOS_TaskIsRunning()) {
PRINTK("taskName = %s\n", g_losTask.runTask->taskName);
PRINTK("taskID = %u\n", g_losTask.runTask->taskID);
}
PRINTK("----- traceback start -----\r\n");
for (index = 0; index < BACKTRACE_MAX_DEPTH; index++) {
if (LR[index] == 0) {
break;
}
PRINTK("traceback %d -- lr = 0x%x\r\n", index, LR[index]);
}
PRINTK("----- traceback end -----\r\n");
}
VOID OSBackTraceInit(VOID)
{
OsBackTraceHookSet(LOS_RecordLR);
}
#endif
@@ -0,0 +1,171 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LOS_BACKTRACE_H
#define _LOS_BACKTRACE_H
#include "los_config.h"
#include "../../kernel/arch/risc-v/V4A/gcc/los_arch_interrupt.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define BACKTRACE_MAX_DEPTH LOSCFG_BACKTRACE_DEPTH
#if (LOSCFG_BACKTRACE_TYPE != 0)
#if (LOSCFG_BACKTRACE_TYPE == 1)
/* The default name of the code section and CSTACK section are given below,
and the user can adjust it according to the linker script file. */
#if defined(__ICCARM__)
/* The default code section name is .text */
#define CODE_SECTION_NAME ".text"
/* The default C stack section name is CSTACK */
#define CSTACK_SECTION_NAME "CSTACK"
#pragma section=CODE_SECTION_NAME
#pragma section=CSTACK_SECTION_NAME
/* Default only one code section. In fact, there may be more than one.
You can define more than one and modify the OsStackDataIsCodeAddr function
to support searching in multiple code sections */
#define CODE_START_ADDR ((UINTPTR)__section_begin(CODE_SECTION_NAME))
#define CODE_END_ADDR ((UINTPTR)__section_end(CODE_SECTION_NAME))
#define CSTACK_START_ADDR ((UINTPTR)__section_begin(CSTACK_SECTION_NAME))
#define CSTACK_END_ADDR ((UINTPTR)__section_end(CSTACK_SECTION_NAME))
#elif defined(__CC_ARM) || defined(__CLANG_ARM)
/* The default code section name is ER_IROM1 */
#define CODE_SECTION_NAME ER_IROM1
/* The default C stack section name is STACK */
#define CSTACK_SECTION_NAME STACK
#define SECTION_START(_name_) _name_##$$Base
#define SECTION_END(_name_) _name_##$$Limit
#define CSTACK_SECTION_START(_name_) SECTION_START(_name_)
#define CSTACK_SECTION_END(_name_) SECTION_END(_name_)
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
extern CHAR *CSTACK_SECTION_START(CSTACK_SECTION_NAME);
extern CHAR *CSTACK_SECTION_END(CSTACK_SECTION_NAME);
extern CHAR *CODE_SECTION_START(CODE_SECTION_NAME);
extern CHAR *CODE_SECTION_END(CODE_SECTION_NAME);
/* Default only one code section. In fact, there may be more than one.
You can define more than one and modify the OsStackDataIsCodeAddr function
to support searching in multiple code sections */
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START(CODE_SECTION_NAME))
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END(CODE_SECTION_NAME))
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START(CSTACK_SECTION_NAME))
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END(CSTACK_SECTION_NAME))
#elif defined(__GNUC__)
/* The default code section start address */
#define CODE_SECTION_START _stext
/* The default code section end address */
#define CODE_SECTION_END _etext
/* The default C stack section start address */
#define CSTACK_SECTION_START _sstack
/* The default C stack section end address */
#define CSTACK_SECTION_END _estack
extern CHAR *CODE_SECTION_START;
extern CHAR *CODE_SECTION_END;
extern CHAR *CSTACK_SECTION_START;
extern CHAR *CSTACK_SECTION_END;
/* Default only one code section. In fact, there may be more than one.
You can define more than one and modify the OsStackDataIsCodeAddr function
to support searching in multiple code sections */
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START)
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END)
#else
#error Unknown compiler.
#endif
#elif (LOSCFG_BACKTRACE_TYPE == 2) || (LOSCFG_BACKTRACE_TYPE == 3)
#if defined(__GNUC__)
/* The default code section start address */
#define CODE_SECTION_START __text_start
/* The default code section end address */
#define CODE_SECTION_END __text_end
/* The default C stack section start address */
#define CSTACK_SECTION_START __except_stack_top
/* The default C stack section end address */
#define CSTACK_SECTION_END __start_and_irq_stack_top
extern CHAR *CODE_SECTION_START;
extern CHAR *CODE_SECTION_END;
extern CHAR *CSTACK_SECTION_START;
extern CHAR *CSTACK_SECTION_END;
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START)
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END)
#else
#error Unknown compiler.
#endif
#endif
/* This function is used to judge whether the data in the stack is a code section address.
The default code section is only one, but there may be more than one. Modify the
judgment condition to support multiple code sections. */
STATIC INLINE BOOL OsStackDataIsCodeAddr(UINTPTR value)
{
if ((value >= CODE_START_ADDR) && (value < CODE_END_ADDR)) {
return TRUE;
}
return FALSE;
}
/* This function is currently used to register the memory leak check hook,
other uses do not need to be called temporarily. */
VOID OSBackTraceInit(VOID);
/* This function is used to print the function call stack. */
VOID LOS_BackTrace(VOID);
/* This function is used to record the function call stack. */
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP);
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
@@ -0,0 +1,34 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("cppsupport") {
sources = [ "los_cppsupport.c" ]
include_dirs = [ "../../utils" ]
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "los_cppsupport.h"
typedef VOID (*InitFunc)(VOID);
INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd)
{
UINTPTR *start;
InitFunc initFunc = NULL;
for (start = (UINTPTR *)initArrayStart; start < (UINTPTR *)initArrayEnd; start++){
initFunc = (InitFunc)(*start);
initFunc();
}
return 0;
}
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
/**
* @defgroup los_cppsupport c++
* @ingroup kernel
*/
#ifndef _LOS_CPPSUPPORT_H
#define _LOS_CPPSUPPORT_H
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_cppsupport
* @brief System cppsupport initialization.
*
* @par Description:
* This API is used to initialize the cppsupport .
* @attention
* <ul>
* <li>initArrayStart is the start address of .init_array section,
* initArrayEnd is the end address of .init_array section.</li>
* <li>initArrayStart must be smaller than initArrayEnd,
* initArrayStart and initArrayEnd should be 4(32 bits platform) or 8(64 bits platform) bytes alignment.</li>
* </ul>
*
*
* @retval 0 always return 0.
* @par Dependency:
* <ul><li>los_cppsupport.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_CPPSUPPORT_H */
@@ -0,0 +1,39 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("cpup") {
sources = [ "los_cpup.c" ]
include_dirs = [
"../../kernel/include",
"../../kernel/arch/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,516 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "los_cpup.h"
#include "securec.h"
#include "los_memory.h"
#include "los_debug.h"
#include "los_tick.h"
#if (LOSCFG_BASE_CORE_CPUP == 1)
/**
* @ingroup los_cpup
* CPU usage-type macro: used for tasks.
*/
#define OS_THREAD_TYPE_TASK 0
/**
* @ingroup los_cpup
* CPU usage-type macro: used for hardware interrupts.
*/
#define OS_THREAD_TYPE_HWI 1
#define OS_CPUP_RECORD_PERIOD (g_sysClock)
LITE_OS_SEC_BSS UINT16 g_cpupInitFlg = 0;
LITE_OS_SEC_BSS OsCpupCB *g_cpup = NULL;
LITE_OS_SEC_BSS UINT64 g_lastRecordTime;
LITE_OS_SEC_BSS UINT16 g_hisPos; /* <current Sampling point of historyTime */
/*****************************************************************************
Function : OsCpupInit
Description: initialization of CPUP
Input : None
Return : LOS_OK or Error Information
*****************************************************************************/
LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit()
{
UINT32 size;
size = g_taskMaxNum * sizeof(OsCpupCB);
g_cpup = (OsCpupCB *)LOS_MemAlloc(m_aucSysMem0, size);
if (g_cpup == NULL) {
return LOS_ERRNO_CPUP_NO_MEMORY;
}
// Ignore the return code when matching CSEC rule 6.6(3).
(VOID)memset_s(g_cpup, size, 0, size);
g_cpupInitFlg = 1;
return LOS_OK;
}
/*****************************************************************************
Function : OsTskCycleStart
Description: start task to get cycles count in current task begining
Input : None
Return : None
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleStart(VOID)
{
UINT32 taskID;
if (g_cpupInitFlg == 0) {
return;
}
taskID = g_losTask.newTask->taskID;
g_cpup[taskID].cpupID = taskID;
g_cpup[taskID].startTime = LOS_SysCycleGet();
return;
}
/*****************************************************************************
Function : OsTskCycleEnd
Description: quit task and get cycle count
Input : None
Return : None
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEnd(VOID)
{
UINT32 taskID;
UINT64 cpuCycle;
if (g_cpupInitFlg == 0) {
return;
}
taskID = g_losTask.runTask->taskID;
if (g_cpup[taskID].startTime == 0) {
return;
}
cpuCycle = LOS_SysCycleGet();
if (cpuCycle < g_cpup[taskID].startTime) {
cpuCycle += g_cyclesPerTick;
}
g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime);
g_cpup[taskID].startTime = 0;
return;
}
/*****************************************************************************
Function : OsTskCycleEndStart
Description: start task to get cycles count in current task ending
Input : None
Return : None
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEndStart(VOID)
{
UINT32 taskID;
UINT64 cpuCycle;
UINT16 loopNum;
if (g_cpupInitFlg == 0) {
return;
}
taskID = g_losTask.runTask->taskID;
cpuCycle = LOS_SysCycleGet();
if (g_cpup[taskID].startTime != 0) {
if (cpuCycle < g_cpup[taskID].startTime) {
cpuCycle += g_cyclesPerTick;
}
g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime);
g_cpup[taskID].startTime = 0;
}
taskID = g_losTask.newTask->taskID;
g_cpup[taskID].cpupID = taskID;
g_cpup[taskID].startTime = cpuCycle;
if ((cpuCycle - g_lastRecordTime) > OS_CPUP_RECORD_PERIOD) {
g_lastRecordTime = cpuCycle;
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
g_cpup[loopNum].historyTime[g_hisPos] = g_cpup[loopNum].allTime;
}
if (g_hisPos == (OS_CPUP_HISTORY_RECORD_NUM - 1)) {
g_hisPos = 0;
} else {
g_hisPos++;
}
}
return;
}
LITE_OS_SEC_TEXT_MINOR static inline UINT16 OsGetPrePos(UINT16 curPos)
{
return (curPos == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : (curPos - 1);
}
LITE_OS_SEC_TEXT_MINOR static VOID OsGetPositions(UINT16 mode, UINT16* curPosAddr, UINT16* prePosAddr)
{
UINT16 curPos;
UINT16 prePos = 0;
curPos = g_hisPos;
if (mode == CPUP_IN_1S) {
curPos = OsGetPrePos(curPos);
prePos = OsGetPrePos(curPos);
} else if (mode == CPUP_LESS_THAN_1S) {
curPos = OsGetPrePos(curPos);
}
*curPosAddr = curPos;
*prePosAddr = prePos;
}
/*****************************************************************************
Function : LOS_SysCpuUsage
Description: get current CPU usage
Input : None
Return : cpupRet:current CPU usage
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_SysCpuUsage(VOID)
{
UINT64 cpuCycleAll = 0;
UINT32 cpupRet = 0;
UINT16 loopNum;
UINT32 intSave;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
// get end time of current task
intSave = LOS_IntLock();
OsTskCycleEnd();
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
cpuCycleAll += g_cpup[loopNum].allTime;
}
if (cpuCycleAll) {
cpupRet = LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION *
g_cpup[g_idleTaskID].allTime) / cpuCycleAll);
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
/*****************************************************************************
Function : LOS_HistorySysCpuUsage
Description: get CPU usage history
Input : mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s
Return : cpupRet:CPU usage history
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode)
{
UINT64 cpuCycleAll = 0;
UINT64 idleCycleAll = 0;
UINT32 cpupRet = 0;
UINT16 loopNum;
UINT16 curPos;
UINT16 prePos = 0;
UINT32 intSave;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
// get end time of current task
intSave = LOS_IntLock();
OsTskCycleEnd();
OsGetPositions(mode, &curPos, &prePos);
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if (mode == CPUP_IN_1S) {
cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
}
if (mode == CPUP_IN_1S) {
idleCycleAll += g_cpup[g_idleTaskID].historyTime[curPos] -
g_cpup[g_idleTaskID].historyTime[prePos];
} else {
idleCycleAll += g_cpup[g_idleTaskID].allTime - g_cpup[g_idleTaskID].historyTime[curPos];
}
if (cpuCycleAll) {
cpupRet = (LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION * idleCycleAll) / cpuCycleAll));
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
/*****************************************************************************
Function : LOS_TaskCpuUsage
Description: get CPU usage of certain task
Input : taskID : task ID
Return : cpupRet:CPU usage of certain task
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuUsage(UINT32 taskID)
{
UINT64 cpuCycleAll = 0;
UINT16 loopNum;
UINT32 intSave;
UINT32 cpupRet = 0;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {
return LOS_ERRNO_CPUP_TSK_ID_INVALID;
}
if (g_cpup[taskID].cpupID != taskID) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
intSave = LOS_IntLock();
OsTskCycleEnd();
/* get total Cycle */
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {
continue;
}
cpuCycleAll += g_cpup[loopNum].allTime;
}
if (cpuCycleAll) {
cpupRet = (UINT32)((LOS_CPUP_PRECISION * g_cpup[taskID].allTime) / cpuCycleAll);
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
/*****************************************************************************
Function : LOS_HistoryTaskCpuUsage
Description: get CPU usage history of certain task
Input : taskID : task ID
: mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s
Return : cpupRet:CPU usage history of task
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode)
{
UINT64 cpuCycleAll = 0;
UINT64 cpuCycleCurTsk = 0;
UINT16 loopNum, curPos;
UINT16 prePos = 0;
UINT32 intSave;
UINT32 cpupRet = 0;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {
return LOS_ERRNO_CPUP_TSK_ID_INVALID;
}
if (g_cpup[taskID].cpupID != taskID) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
intSave = LOS_IntLock();
OsTskCycleEnd();
OsGetPositions(mode, &curPos, &prePos);
/* get total Cycle in history */
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {
continue;
}
if (mode == CPUP_IN_1S) {
cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
}
if (mode == CPUP_IN_1S) {
cpuCycleCurTsk += g_cpup[taskID].historyTime[curPos] - g_cpup[taskID].historyTime[prePos];
} else {
cpuCycleCurTsk += g_cpup[taskID].allTime - g_cpup[taskID].historyTime[curPos];
}
if (cpuCycleAll) {
cpupRet = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll);
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode)
{
UINT16 loopNum;
UINT16 curPos;
UINT16 prePos = 0;
UINT32 intSave;
UINT64 cpuCycleAll = 0;
UINT64 cpuCycleCurTsk = 0;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
if (cpupInfo == NULL) {
return LOS_ERRNO_CPUP_TASK_PTR_NULL;
}
intSave = LOS_IntLock();
OsTskCycleEnd();
OsGetPositions(mode, &curPos, &prePos);
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
(g_cpup[loopNum].status == 0)) {
continue;
}
if (mode == CPUP_IN_1S) {
cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
}
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
(g_cpup[loopNum].status == 0)) {
continue;
}
if (mode == CPUP_IN_1S) {
cpuCycleCurTsk += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleCurTsk += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
cpupInfo[loopNum].usStatus = g_cpup[loopNum].status;
if (cpuCycleAll) {
cpupInfo[loopNum].uwUsage = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll);
}
cpuCycleCurTsk = 0;
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return LOS_OK;
}
/*****************************************************************************
Function : LOS_CpupUsageMonitor
Description: Get CPU usage history of certain task.
Input : type: cpup type, SYS_CPU_USAGE and TASK_CPU_USAGE
: taskID: task ID, Only in SYS_CPU_USAGE type, taskID is invalid
: mode: mode, CPUP_IN_10S = usage in 10s, CPUP_IN_1S = usage in last 1s, CPUP_LESS_THAN_1S = less than 1s
Return : LOS_OK on success, or OS_ERROR on failure
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID)
{
UINT32 ret;
LosTaskCB *taskCB = NULL;
switch (type) {
case SYS_CPU_USAGE:
if (mode == CPUP_IN_10S) {
PRINTK("\nSysCpuUsage in 10s: ");
} else if (mode == CPUP_IN_1S) {
PRINTK("\nSysCpuUsage in 1s: ");
} else {
PRINTK("\nSysCpuUsage in <1s: ");
}
ret = LOS_HistorySysCpuUsage(mode);
PRINTK("%d.%d", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
break;
case TASK_CPU_USAGE:
if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) {
PRINT_ERR("\nThe taskid is invalid.\n");
return OS_ERROR;
}
taskCB = OS_TCB_FROM_TID(taskID);
if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED)) {
PRINT_ERR("\nThe taskid is invalid.\n");
return OS_ERROR;
}
if (mode == CPUP_IN_10S) {
PRINTK("\nCPUusage of taskID %d in 10s: ", taskID);
} else if (mode == CPUP_IN_1S) {
PRINTK("\nCPUusage of taskID %d in 1s: ", taskID);
} else {
PRINTK("\nCPUusage of taskID %d in <1s: ", taskID);
}
ret = LOS_HistoryTaskCpuUsage(taskID, mode);
PRINTK("%u.%u", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
break;
default:
PRINT_ERR("\nThe type is invalid.\n");
return OS_ERROR;
}
return LOS_OK;
}
#endif /* LOSCFG_BASE_CORE_CPUP */
@@ -0,0 +1,366 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
/**
* @defgroup los_cpup CPU usage
* @ingroup kernel
*/
#ifndef _LOS_CPUP_H
#define _LOS_CPUP_H
#include "los_interrupt.h"
#include "los_task.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_cpup
* CPU usage error code: The request for memory fails.
*
* Value: 0x02001e00
*
* Solution: Decrease the maximum number of tasks.
*/
#define LOS_ERRNO_CPUP_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x00)
/**
* @ingroup los_cpup
* CPU usage error code: The pointer to an input parameter is NULL.
*
* Value: 0x02001e01
*
* Solution: Check whether the pointer to the input parameter is usable.
*/
#define LOS_ERRNO_CPUP_TASK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x01)
/**
* @ingroup los_cpup
* CPU usage error code: The CPU usage is not initialized.
*
* Value: 0x02001e02
*
* Solution: Check whether the CPU usage is initialized.
*/
#define LOS_ERRNO_CPUP_NO_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x02)
/**
* @ingroup los_cpup
* CPU usage error code: The number of threads is invalid.
*
* Value: 0x02001e03
*
* Solution: Check whether the number of threads is applicable for the current operation.
*/
#define LOS_ERRNO_CPUP_MAXNUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x03)
/**
* @ingroup los_cpup
* CPU usage error code: The target thread is not created.
*
* Value: 0x02001e04
*
* Solution: Check whether the target thread is created.
*/
#define LOS_ERRNO_CPUP_THREAD_NO_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x04)
/**
* @ingroup los_cpup
* CPU usage error code: The target task ID is invalid.
*
* Value: 0x02001e05
*
* Solution: Check whether the target task ID is applicable for the current operation.
*/
#define LOS_ERRNO_CPUP_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x05)
/**
* @ingroup los_cpup
* Sum of cpup with all tasks. It means the value of cpup is a permillage.
*/
#define LOS_CPUP_PRECISION 1000
/**
* @ingroup los_cpup
* Multiple of current cpup precision change to percent.
*/
#define LOS_CPUP_PRECISION_MULT (LOS_CPUP_PRECISION / 100)
/**
* @ingroup los_cpup
* Number of historical running time records
*/
#define OS_CPUP_HISTORY_RECORD_NUM 10
/**
* @ingroup los_cpup
* Count the CPU usage structures of a task.
*/
typedef struct {
UINT32 cpupID; /**< Task ID */
UINT16 status; /**< Task status */
UINT64 allTime; /**< Total running time */
UINT64 startTime; /**< Time before a task is invoked */
UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM]; /**< Historical running time */
} OsCpupCB;
extern OsCpupCB *g_cpup;
/**
* @ingroup los_cpup
* @brief Initialization cpup.
*
* @par Description:
* This API is used to initialization cpup.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param None.
*
* @retval UINT32 Initialization result.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern UINT32 OsCpupInit(VOID);
/**
* @ingroup los_cpup
* @brief Start task to get cycles count in current task ending.
*
* @par Description:
* This API is used to start task to get cycles count in current task ending.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param None.
*
* @retval None.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern VOID OsTskCycleEndStart(VOID);
/**
* @ingroup los_cpup
* Count the CPU usage structures of all tasks.
*/
typedef struct tagCpupInfo {
UINT16 usStatus; /**< save the cur task status */
UINT32 uwUsage; /**< Usage. The value range is [0,1000]. */
} CPUP_INFO_S;
/**
* @ingroup los_monitor
* Type of the CPU usage query.
*/
typedef enum {
SYS_CPU_USAGE = 0, /* system cpu occupancy rate */
TASK_CPU_USAGE, /* task cpu occupancy rate */
} CPUP_TYPE_E;
/**
* @ingroup los_monitor
* Mode of the CPU usage query.
*/
typedef enum {
CPUP_IN_10S = 0, /* cpu occupancy rate in 10s */
CPUP_IN_1S, /* cpu occupancy rate in 1s */
CPUP_LESS_THAN_1S, /* cpu occupancy rate less than 1s, if the input mode is none of them, it will be this. */
} CPUP_MODE_E;
/**
* @ingroup los_cpup
* @brief Obtain the current CPU usage.
*
* @par Description:
* This API is used to obtain the current CPU usage.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, error codes will be returned.</li>
* <li> The precision of the CPU usage can be adjusted by changing the value of the CPUP_PRECISION macro.</li>
* </ul>
*
* @param None.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #cpup [0,1000], current CPU usage, of which the precision is adjustable.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_SysCpuUsage
*/
extern UINT32 LOS_SysCpuUsage(VOID);
/**
* @ingroup los_cpup
* @brief Obtain the historical CPU usage.
*
* @par Description:
* This API is used to obtain the historical CPU usage.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.</li>
* </ul>
*
* @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s will be
* obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained. Other values
* indicate that the CPU usage in the period that is less than 1s will be obtained.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #cpup [0,1000], historical CPU usage, of which the precision is adjustable.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_HistoryTaskCpuUsage
*/
extern UINT32 LOS_HistorySysCpuUsage(UINT16 mode);
/**
* @ingroup los_cpup
* @brief Obtain the CPU usage of a specified task.
*
* @par Description:
* This API is used to obtain the CPU usage of a task specified by a passed-in task ID.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.</li>
* <li>The passed-in task ID must be valid and the task specified by the task ID must be created. Otherwise,
* the CPU usage fails to be obtained.</li>
* </ul>
*
* @param taskID [IN] UINT32. Task ID.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #OS_ERRNO_CPUP_TSK_ID_INVALID 0x02001e05: The target task ID is invalid.
* @retval #OS_ERRNO_CPUP_THREAD_NO_CREATED 0x02001e04: The target thread is not created.
* @retval #cpup [0,1000], CPU usage of the specified task.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_HistoryTaskCpuUsage
*/
extern UINT32 LOS_TaskCpuUsage(UINT32 taskID);
/**
* @ingroup los_cpup
* @brief Obtain the historical CPU usage of a specified task.
*
* @par Description:
* This API is used to obtain the historical CPU usage of a task specified by a passed-in task ID.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise,
* the CPU usage fails to be obtained.</li>
* <li>The passed-in task ID must be valid and the task specified by the task ID must be created. Otherwise,
* the CPU usage fails to be obtained.</li>
* </ul>
*
* @param taskID [IN] UINT32. Task ID.
* @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s
* will be obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained.
* Other values indicate that the CPU usage in the period that is less than 1s will be obtained.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #OS_ERRNO_CPUP_TSK_ID_INVALID 0x02001e05: The target task ID is invalid.
* @retval #OS_ERRNO_CPUP_THREAD_NO_CREATED 0x02001e04: The target thread is not created.
* @retval #cpup [0,1000], CPU usage of the specified task.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_HistorySysCpuUsage
*/
extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode);
/**
* @ingroup los_cpup
* @brief Obtain the CPU usage of all tasks.
*
* @par Description:
* This API is used to obtain the CPU usage of all tasks according to maximum number of threads.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.</li>
* <li>The input parameter pointer must not be NULL, Otherwise, the CPU usage fails to be obtained.</li>
* </ul>
*
* @param cpupInfo [OUT]Type. CPUP_INFO_S* Pointer to the task CPUP information structure to be obtained.
* @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s
* will be obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained.
* Other values indicate that the CPU usage in the period that is less than 1s will be obtained.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #OS_ERRNO_CPUP_TASK_PTR_NULL 0x02001e01: The input parameter pointer is NULL.
* @retval #LOS_OK 0x00000000: The CPU usage of all tasks is successfully obtained.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_SysCpuUsage
*/
extern UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode);
/**
* @ingroup los_monitor
* @brief Obtain CPU usage history of certain task.
*
* @par Description:
* This API is used to obtain CPU usage history of certain task.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, -1 will be returned.</li>
* <li> Only in SYS_CPU_USAGE type, uwTaskID is invalid.</li>
* </ul>
*
* @param type [IN] cpup type, SYS_CPU_USAGE and TASK_CPU_USAGE
* @param mode [IN] mode,CPUP_IN_10S = usage in 10s,CPUP_IN_1S = usage in last 1s,
* CPUP_LESS_THAN_1S = less than 1s, if the input mode is none of them, it will be as CPUP_LESS_THAN_1S.
* @param taskID [IN] task ID, Only in SYS_CPU_USAGE type, taskID is invalid
*
* @retval #OS_ERROR -1:CPU usage info obtain failed.
* @retval #LOS_OK 0:CPU usage info is successfully obtained.
* @par Dependency:
* <ul><li>los_monitor.h: the header file that contains the API declaration.</li></ul>
* @see LOS_CpupUsageMonitor
*/
extern UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_CPUP_H */
@@ -0,0 +1,41 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("exchook") {
sources = [
"los_exc_info.c",
"los_exchook.c",
]
include_dirs = [
"../../kernel/arch/include",
"../../kernel/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,298 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "los_exc_info.h"
#include "securec.h"
#include "los_debug.h"
#include "los_interrupt.h"
#include "los_task.h"
#include "los_exchook.h"
#include "los_membox.h"
#include "los_memory.h"
#if (LOSCFG_PLATFORM_EXC == 1)
#define EXC_MSG_ARRAY_INIT_VALUE 0xff
#define EXC_INT_STATUS_LEN (OS_NVIC_INT_ENABLE_SIZE + OS_NVIC_INT_PEND_SIZE + \
OS_NVIC_INT_ACT_SIZE + OS_NVIC_INT_PRI_SIZE + \
OS_NVIC_EXCPRI_SIZE + OS_NVIC_SHCSR_SIZE + \
OS_NVIC_INT_CTRL_SIZE)
UINT32 g_excQueueMaxNum;
UINT32 g_excMemMaxNum;
VOID *g_excContent = NULL;
UINT32 g_excArraySize = MAX_EXC_MEM_SIZE;
UINT8 g_excMsgArray[MAX_EXC_MEM_SIZE];
STATIC ExcInfoArray g_excArray[OS_EXC_TYPE_MAX];
STATIC UINT32 OsExcSaveIntStatus(UINT32 type, VOID *arg)
{
UINT32 ret;
UINTPTR excContentEnd = (UINTPTR)MAX_INT_INFO_SIZE + (UINTPTR)g_excContent;
(VOID)arg;
*((UINT32 *)g_excContent) = type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = EXC_INT_STATUS_LEN;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
/* save IRQ ENABLE reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_SETENA_BASE, OS_NVIC_INT_ENABLE_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_ENABLE_SIZE;
/* save IRQ PEND reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_SETPEND_BASE, OS_NVIC_INT_PEND_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_PEND_SIZE;
/* save IRQ ACTIVE reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_INT_ACT_BASE, OS_NVIC_INT_ACT_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_ACT_SIZE;
/* save IRQ Priority reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_PRI_BASE, OS_NVIC_INT_PRI_SIZE);
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_PRI_SIZE;
/* save Exception Priority reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_EXCPRI_BASE, OS_NVIC_EXCPRI_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_EXCPRI_SIZE;
/* save IRQ Handler & SHCSR */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_SHCSR, OS_NVIC_SHCSR_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_SHCSR_SIZE;
/* save IRQ Control & ICSR */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_INT_CTRL, OS_NVIC_INT_CTRL_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_CTRL_SIZE;
return LOS_OK;
}
STATIC UINT32 OsExcMemMsgGet(UINT32 type, VOID *arg)
{
UINT32 count;
UINT32 memNum = *(UINT32 *)arg;
UINTPTR memMsgEnd = (UINTPTR)g_excContent + MAX_MEM_INFO_SIZE;
*((UINT32 *)g_excContent) = type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = sizeof(MemInfoCB) * memNum;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
count = OsMemboxExcInfoGet(memNum, g_excContent);
if (count < memNum) {
g_excContent = (UINT8 *)g_excContent + sizeof(MemInfoCB) * count;
(VOID)OsMemExcInfoGet(memNum - count, g_excContent);
}
g_excContent = (VOID *)memMsgEnd;
return LOS_OK;
}
STATIC UINT32 OsExcContentGet(UINT32 type, VOID *arg)
{
UINTPTR excContentEnd = MAX_EXC_MEM_SIZE + (UINTPTR)g_excMsgArray;
errno_t ret;
(VOID)arg;
/* save exception info */
*((UINT32 *)g_excContent) = type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = sizeof(ExcInfo) + sizeof(EXC_CONTEXT_S);
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
ret = memcpy_s((VOID *)g_excContent, excContentEnd - (UINTPTR)g_excContent,
(VOID *)&g_excInfo, sizeof(ExcInfo));
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + sizeof(ExcInfo);
ret = memcpy_s((VOID *)g_excContent, excContentEnd - (UINTPTR)g_excContent,
g_excInfo.context, sizeof(EXC_CONTEXT_S));
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + sizeof(EXC_CONTEXT_S);
return LOS_OK;
}
STATIC UINT32 OsExcHookFunc(UINT32 type, UINT32 index, UINT32 loop, UINT32 len, EXC_INFO_SAVE_CALLBACK func)
{
UINT32 i;
*((UINT32 *)g_excContent) = (UINT32)type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = len * loop;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
for (i = index; i < loop; i++) {
(VOID)func(i, g_excContent);
g_excContent = (UINT8 *)g_excContent + len;
}
return LOS_OK;
}
#if (LOSCFG_BASE_IPC_QUEUE == 1)
STATIC UINT32 OsExcQueueMsgGet(UINT32 type, VOID *arg)
{
UINT32 len = sizeof(QUEUE_INFO_S);
UINT32 loop = *(UINT32 *)arg;
return OsExcHookFunc(type, 1, loop, len, (EXC_INFO_SAVE_CALLBACK)LOS_QueueInfoGet);
}
#endif
STATIC UINT32 OsExcTaskMsgGet(UINT32 type, VOID *arg)
{
UINT32 len = sizeof(TSK_INFO_S);
UINT32 loop = *(UINT32 *)arg;
return OsExcHookFunc(type, 0, loop, len, (EXC_INFO_SAVE_CALLBACK)LOS_TaskInfoGet);
}
#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
STATIC UINT32 OsExcTskSwitchMsgGet(UINT32 type, VOID *arg)
{
UINT32 len;
UINT32 loop;
UINT32 taskSwitchCount;
TaskSwitchInfo *taskSwitchInfo = NULL;
UINT32 i;
/* not necessary, just for macro int library */
taskSwitchInfo = (TaskSwitchInfo *)arg;
taskSwitchCount = taskSwitchInfo->cntInfo.maxCnt;
len = sizeof(UINT32) + (sizeof(CHAR) * LOS_TASK_NAMELEN);
if (taskSwitchInfo->cntInfo.isFull) {
i = taskSwitchInfo->idx;
loop = i + taskSwitchCount;
} else {
i = 0;
loop = taskSwitchInfo->idx;
}
return OsExcHookFunc(type, i, loop, len, (EXC_INFO_SAVE_CALLBACK)LOS_TaskSwitchInfoGet);
}
#endif
VOID OsExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg)
{
ExcInfoArray *excInfo = NULL;
if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) {
PRINT_ERR("HalExcRegister ERROR!\n");
return;
}
excInfo = &(g_excArray[type]);
if (excInfo->valid == TRUE) {
return;
}
excInfo->type = type;
excInfo->fnExcInfoCb = func;
excInfo->arg = arg;
excInfo->valid = TRUE;
}
STATIC VOID OsExcMsgDump(VOID)
{
UINT32 index;
/* Ignore the return code when matching CSEC rule 6.6(4). */
(VOID)memset_s(g_excMsgArray, g_excArraySize, EXC_MSG_ARRAY_INIT_VALUE, g_excArraySize);
*((UINT32 *)g_excContent) = MAX_EXC_MEM_SIZE; /* The total length of exception information. */
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
for (index = 0; index < OS_EXC_TYPE_MAX; index++) {
if (!g_excArray[index].valid) {
continue;
}
g_excArray[index].fnExcInfoCb(g_excArray[index].type, g_excArray[index].arg);
}
*((UINT32 *)g_excContent) = OS_EXC_TYPE_MAX;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
return;
}
VOID OsExcMsgDumpInit(VOID)
{
g_excQueueMaxNum = LOSCFG_BASE_IPC_QUEUE_LIMIT;
g_excMemMaxNum = OS_SYS_MEM_NUM;
g_excContent = (VOID *)g_excMsgArray;
OsExcRegister(OS_EXC_TYPE_CONTEXT, OsExcContentGet, NULL);
OsExcRegister(OS_EXC_TYPE_TSK, OsExcTaskMsgGet, &g_taskMaxNum);
#if (LOSCFG_BASE_IPC_QUEUE == 1)
OsExcRegister(OS_EXC_TYPE_QUE, OsExcQueueMsgGet, &g_excQueueMaxNum);
#endif
OsExcRegister(OS_EXC_TYPE_NVIC, OsExcSaveIntStatus, NULL);
#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
OsExcRegister(OS_EXC_TYPE_TSK_SWITCH, OsExcTskSwitchMsgGet, &g_taskSwitchInfo);
#endif
OsExcRegister(OS_EXC_TYPE_MEM, OsExcMemMsgGet, &g_excMemMaxNum);
(VOID)LOS_RegExcHook(EXC_INTERRUPT, (ExcHookFn)OsExcMsgDump);
}
#endif
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "los_config.h"
#include "los_task.h"
#include "los_queue.h"
#include "los_memory.h"
#include "los_arch_interrupt.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#if (LOSCFG_PLATFORM_EXC == 1)
#define INFO_TYPE_AND_SIZE 8
#define MAX_SCENE_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(ExcInfo) + sizeof(EXC_CONTEXT_S))
#define MAX_TSK_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1))
#if (LOSCFG_BASE_IPC_QUEUE == 1)
#define MAX_QUEUE_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(QUEUE_INFO_S) * LOSCFG_BASE_IPC_QUEUE_LIMIT)
#else
#define MAX_QUEUE_INFO_SIZE (0)
#endif
#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
#define MAX_SWITCH_INFO_SIZE (INFO_TYPE_AND_SIZE + (sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN) * OS_TASK_SWITCH_INFO_COUNT)
#else
#define MAX_SWITCH_INFO_SIZE (0)
#endif
#define MAX_MEM_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(MemInfoCB) * OS_SYS_MEM_NUM)
#define MAX_EXC_MEM_SIZE (INFO_TYPE_AND_SIZE + MAX_SCENE_INFO_SIZE + MAX_TSK_INFO_SIZE + MAX_QUEUE_INFO_SIZE + MAX_INT_INFO_SIZE + MAX_SWITCH_INFO_SIZE + MAX_MEM_INFO_SIZE)
typedef enum {
OS_EXC_TYPE_CONTEXT = 0,
OS_EXC_TYPE_TSK = 1,
OS_EXC_TYPE_QUE = 2,
OS_EXC_TYPE_NVIC = 3,
OS_EXC_TYPE_TSK_SWITCH = 4,
OS_EXC_TYPE_MEM = 5,
OS_EXC_TYPE_MAX = 6
} ExcInfoType;
typedef struct {
ExcInfoType flag;
UINT32 length;
ExcInfo info;
EXC_CONTEXT_S context;
} ExcContextInfoArray;
typedef struct {
ExcInfoType flag;
UINT32 length;
TSK_INFO_S taskInfo[LOSCFG_BASE_CORE_TSK_LIMIT + 1];
} ExcTaskInfoArray;
typedef struct {
ExcInfoType flag;
UINT32 length;
QUEUE_INFO_S queueInfo[LOSCFG_BASE_CORE_TSK_LIMIT];
} ExcQueueInfoArray;
typedef struct {
UINT32 totalLen;
ExcContextInfoArray excInfo;
ExcTaskInfoArray taskInfo;
ExcQueueInfoArray queueInfo;
} ExcMsgArray;
typedef UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID *);
typedef struct {
ExcInfoType type;
UINT32 valid;
EXC_INFO_SAVE_CALLBACK fnExcInfoCb;
VOID *arg;
} ExcInfoArray;
VOID OsExcMsgDumpInit(VOID);
extern UINT8 g_excMsgArray[MAX_EXC_MEM_SIZE];
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
@@ -0,0 +1,136 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "los_exchook.h"
#include "los_context.h"
#ifndef LOSCFG_BASE_EXC_HOOK_LIMIT
#define LOSCFG_BASE_EXC_HOOK_LIMIT 16
#endif
struct Node {
ExcHookFn excHookFn;
struct Node *next;
};
STATIC struct Node g_excNodes[LOSCFG_BASE_EXC_HOOK_LIMIT];
STATIC struct Node *g_excHeads[EXC_TYPE_END + 1]; /* EXC_TYPE_END is used for the free list. */
STATIC VOID DoExcHookInRegOrder(EXC_TYPE excType, struct Node *node)
{
if (node != NULL) {
DoExcHookInRegOrder(excType, node->next);
node->excHookFn(excType);
}
}
STATIC VOID DoExcHook(EXC_TYPE excType)
{
UINT32 intSave;
if (excType >= EXC_TYPE_END) {
return;
}
intSave = LOS_IntLock();
DoExcHookInRegOrder(excType, g_excHeads[excType]);
LOS_IntRestore(intSave);
}
STATIC struct Node *GetFreeNode(VOID)
{
struct Node *node = NULL;
int i;
if (g_excHeads[EXC_TYPE_END] == NULL) {
if (g_excNodes[0].excHookFn != NULL) {
/* no free node now */
return NULL;
} else {
/* Initialize the free list */
for (i = 0; i < LOSCFG_BASE_EXC_HOOK_LIMIT; ++i) {
g_excNodes[i].next = g_excHeads[EXC_TYPE_END];
g_excHeads[EXC_TYPE_END] = &g_excNodes[i];
}
OsExcHookRegister(DoExcHook);
}
}
node = g_excHeads[EXC_TYPE_END];
g_excHeads[EXC_TYPE_END] = node->next;
return node;
}
UINT32 LOS_RegExcHook(EXC_TYPE excType, ExcHookFn excHookFn)
{
UINT32 intSave;
struct Node *node = NULL;
if (excType >= EXC_TYPE_END || excHookFn == NULL) {
return LOS_ERRNO_SYS_PTR_NULL;
}
intSave = LOS_IntLock();
node = GetFreeNode();
if (node == NULL) {
LOS_IntRestore(intSave);
return LOS_ERRNO_SYS_HOOK_IS_FULL;
}
node->excHookFn = excHookFn;
node->next = g_excHeads[excType];
g_excHeads[excType] = node;
LOS_IntRestore(intSave);
return LOS_OK;
}
UINT32 LOS_UnRegExcHook(EXC_TYPE excType, ExcHookFn excHookFn)
{
UINT32 intSave;
struct Node *node = NULL;
struct Node *preNode = NULL;
if (excType >= EXC_TYPE_END || excHookFn == NULL) {
return LOS_ERRNO_SYS_PTR_NULL;
}
intSave = LOS_IntLock();
for (node = g_excHeads[excType]; node != NULL; node = node->next) {
if (node->excHookFn == excHookFn) {
if (preNode) {
preNode->next = node->next;
} else {
g_excHeads[excType] = node->next;
}
node->excHookFn = NULL;
node->next = g_excHeads[EXC_TYPE_END];
g_excHeads[EXC_TYPE_END] = node;
}
preNode = node;
}
LOS_IntRestore(intSave);
return LOS_OK;
}
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
/**
* @defgroup los_exchook Exception hooks
* @ingroup kernel
*/
#ifndef _LOS_EXCHOOK_H
#define _LOS_EXCHOOK_H
#include "los_tick.h"
#include "los_debug.h"
#include "los_arch_interrupt.h"
#include "los_interrupt.h"
#include "los_task.h"
#include "los_queue.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_exchook
* @brief: System exception hooks register function.
*
* @par Description:
* This API is used to register exception hooks.
* Hooks will be invoked in reverse order.
*
* @attention:
* <ul><li>This function should not be call in excHookFn.</li></ul>
*
* @param: None.
*
* @retval: LOS_OK success.
* LOS_ERRNO_SYS_HOOK_IS_FULL too many hooks registered. @see LOSCFG_BASE_EXC_HOOK_LIMIT
* LOS_ERRNO_SYS_PTR_NULL excHookFn is null or invalid excType.
*
* @par Dependency:
* <ul><li>los_exchook.h: the header file that contains the API declaration.</li></ul>
* @see None.
*
* */
extern UINT32 LOS_RegExcHook(EXC_TYPE excType, ExcHookFn excHookFn);
/**
* @ingroup los_exchook
* @brief: System exception hooks unregister function.
*
* @par Description:
* This API is used to unregister exception hooks.
*
* @attention:
* <ul><li>This function should not be call in excHookFn.</li></ul>
*
* @param: None.
*
* @retval: LOS_OK success.
* LOS_ERRNO_SYS_PTR_NULL excHookFn is null or invalid excType.
*
* @par Dependency:
* <ul><li>los_exchook.h: the header file that contains the API declaration.</li></ul>
* @see None.
*
* */
extern UINT32 LOS_UnRegExcHook(EXC_TYPE excType, ExcHookFn excHookFn);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_EXCHOOK_H */
@@ -0,0 +1,60 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("fs_operations") {
sources = [
"./fs.c",
]
include_dirs = [
"../../../kernel/arch/include",
"../../../kernel/include",
"../../../utils",
"../../../kal/posix/include",
"./",
]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
declare_args() {
enable_ohos_kernel_liteos_m_fatfs = true
enable_ohos_kernel_liteos_m_littlefs = true
}
group("fs") {
deps = []
deps += [ ".:fs_operations" ]
if (enable_ohos_kernel_liteos_m_fatfs == true) {
deps += [ "fatfs:fatfs" ]
}
if (enable_ohos_kernel_liteos_m_littlefs == true) {
deps += [ "littlefs:littlefs" ]
}
}
@@ -0,0 +1,51 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("fatfs") {
sources = [
"//third_party/FatFs/source/diskio.c",
"//third_party/FatFs/source/ff.c",
"//third_party/FatFs/source/ffsystem.c",
"//third_party/FatFs/source/ffunicode.c",
"fatfs.c",
]
include_dirs = [
"../",
"../../../kernel/arch/include",
"../../../kernel/include",
"../../../utils",
"../../../kal/cmsis",
"../../../kal/posix/include",
"//third_party/bounds_checking_function/include",
"//third_party/FatFs/source/",
]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _FATFS_H
#define _FATFS_H
#include "fcntl.h"
#include "dirent.h"
#include "unistd.h"
#include "sys/mount.h"
#include "sys/stat.h"
#include "sys/statfs.h"
#include "fs_config.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#ifndef FAT_MAX_OPEN_FILES
#define FAT_MAX_OPEN_FILES 50
#endif /* FAT_MAX_OPEN_FILES */
/* Format options */
#define FMT_FAT 0x01
#define FMT_FAT32 0x02
#define FMT_ANY 0x07
int fatfs_mount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data);
int fatfs_umount(const char *target);
int fatfs_umount2(const char *target, int flag);
int fatfs_open(const char *path, int oflag, ...);
int fatfs_close(int fd);
ssize_t fatfs_read(int fd, void *buf, size_t nbyte);
ssize_t fatfs_write(int fd, const void *buf, size_t nbyte);
off_t fatfs_lseek(int fd, off_t offset, int whence);
int fatfs_unlink(const char *path);
int fatfs_fstat(int fd, struct stat *buf);
int fatfs_stat(const char *path, struct stat *buf);
int fatfs_fsync(int fd);
int fatfs_mkdir(const char *path, mode_t mode);
DIR *fatfs_opendir(const char *dirName);
struct dirent *fatfs_readdir(DIR *dir);
int fatfs_closedir(DIR *dir);
int fatfs_rmdir(const char *path);
int fatfs_rename(const char *oldName, const char *newName);
int fatfs_statfs(const char *path, struct statfs *buf);
int fatfs_ftruncate(int fd, off_t length);
/**
* @brief divide a physical drive (SD card, U disk, and MMC card), this function is OHOS-specific
* @param pdrv physical drive number.
* @param partTbl list of partition size to create on the drive.
* -- item is <= 100: specifies the partition size in percentage of the entire drive space.
* -- item is > 100: specifies number of sectors.
* @return fdisk result
* @retval -1 fdisk error
* @retval 0 fdisk successful
*/
int fatfs_fdisk(int pdrv, const unsigned int *partTbl);
/**
* @brief format FAT device (SD card, U disk, and MMC card), this function is OHOS-specific
* @param dev device name.
* @param sectors sectors per cluster, can be 0 OR power of 2. The sector size for standard FAT volumes is 512 bytes.
* -- sector number is 0 OR >128: automatically choose the appropriate cluster size.
* -- sector number is 1 ~ 128: cluster size = sectors per cluster * 512B.
* @param option file system type.
* -- FMT_FAT
* -- FMT_FAT32
* -- FMT_ANY
* @return format result
* @retval -1 format error
* @retval 0 format successful
*/
int fatfs_format(const char *dev, int sectors, int option);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _FATFS_H */
@@ -0,0 +1,552 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "fs_operations.h"
#include "los_config.h"
#ifdef LOSCFG_SUPPORT_FATFS
#include "fatfs.h"
#endif
#include "dirent.h"
#include "errno.h"
#include "fcntl.h"
#include "securec.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/mount.h"
#include "sys/statfs.h"
#include "sys/stat.h"
#include "unistd.h"
struct FsMap g_fsmap[MAX_FILESYSTEM_LEN] = {0};
struct FsMap *g_fs = NULL;
#ifdef LOSCFG_NET_LWIP_SACK
#include "lwip/lwipopts.h"
#include "lwip/sockets.h"
#define CONFIG_NSOCKET_DESCRIPTORS LWIP_CONFIG_NUM_SOCKETS
#else
#define CONFIG_NSOCKET_DESCRIPTORS 0
#endif
#define CONFIG_NFILE_DESCRIPTORS FAT_MAX_OPEN_FILES /* only for random currently */
#ifdef LOSCFG_RANDOM_DEV
#include "hks_client.h"
#define RANDOM_DEV_FD CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS
#define RANDOM_DEV_PATH "/dev/random"
#endif
#define FREE_AND_SET_NULL(ptr) do { \
free(ptr); \
ptr = NULL; \
} while (0)
#ifdef LOSCFG_RANDOM_DEV
/**
* @brief Get canonical form of a given path based on cwd(Current working directory).
*
* @param cwd Indicates the current working directory.
* @param path Indicates the path to be canonicalization.
* @param buf Indicates the pointer to the buffer where the result will be return.
* @param bufSize Indicates the size of the buffer.
* @return Returns the length of the canonical path.
*
* @attention if path is an absolute path, cwd is ignored. if cwd if not specified, it is assumed to be root('/').
* if the buffer is not big enough the result will be truncated, but the return value will always be the
* length of the canonical path.
*/
static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, size_t bufSize)
{
size_t offset;
if (!path) {
path = "";
}
if (!cwd || path[0] == '/') {
cwd = "";
}
offset = strlen("///") + 1; // three '/' and one '\0'
size_t tmpLen = strlen(cwd) + strlen(path) + offset;
char *tmpBuf = (char *)malloc(tmpLen);
if (tmpBuf == NULL) {
return FS_SUCCESS;
}
if (-1 == sprintf_s(tmpBuf, tmpLen, "/%s/%s/", cwd, path)) {
free(tmpBuf);
return FS_SUCCESS;
}
char *p;
/* replace /./ to / */
offset = strlen("/./") - 1;
while ((p = strstr(tmpBuf, "/./")) != NULL) {
if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
free(tmpBuf);
return FS_SUCCESS;
}
}
/* replace // to / */
while ((p = strstr(tmpBuf, "//")) != NULL) {
if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + 1, tmpLen - (p - tmpBuf) - 1)) {
free(tmpBuf);
return FS_SUCCESS;
}
}
/* handle /../ (e.g., replace /aa/bb/../ to /aa/) */
offset = strlen("/../") - 1;
while ((p = strstr(tmpBuf, "/../")) != NULL) {
char *start = p;
while (start > tmpBuf && *(start - 1) != '/') {
--start;
}
if (EOK != memmove_s(start, tmpLen - (start - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
free(tmpBuf);
return FS_SUCCESS;
}
}
size_t totalLen = strlen(tmpBuf);
/* strip the last / */
if (totalLen > 1 && tmpBuf[totalLen - 1] == '/') {
tmpBuf[--totalLen] = 0;
}
if (!buf || bufSize == 0) {
free(tmpBuf);
return totalLen;
}
if (EOK != memcpy_s(buf, bufSize, tmpBuf, (((totalLen + 1) > bufSize) ? bufSize : (totalLen + 1)))) {
free(tmpBuf);
return FS_SUCCESS;
}
buf[bufSize - 1] = 0;
free(tmpBuf);
return totalLen;
}
#endif
static void InitMountInfo(void)
{
#if (LOSCFG_SUPPORT_FATFS == 1)
extern struct MountOps g_fatfsMnt;
extern struct FileOps g_fatfsFops;
g_fsmap[0].fileSystemtype = strdup("fat");
g_fsmap[0].fsMops = &g_fatfsMnt;
g_fsmap[0].fsFops = &g_fatfsFops;
#endif
#if (LOSCFG_SUPPORT_LITTLEFS == 1)
extern struct MountOps g_lfsMnt;
extern struct FileOps g_lfsFops;
g_fsmap[1].fileSystemtype = strdup("littlefs");
g_fsmap[1].fsMops = &g_lfsMnt;
g_fsmap[1].fsFops = &g_lfsFops;
#endif
}
static struct FsMap *MountFindfs(const char *fileSystemtype)
{
struct FsMap *m = NULL;
for (int i = 0; i < MAX_FILESYSTEM_LEN; i++) {
m = &(g_fsmap[i]);
if (m->fileSystemtype && strcmp(fileSystemtype, m->fileSystemtype) == 0) {
return m;
}
}
return NULL;
}
int mount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data)
{
static int initFlag = 0;
if (initFlag == 0) {
InitMountInfo();
initFlag = 1;
}
g_fs = MountFindfs(filesystemtype);
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Mount == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Mount(source, target, filesystemtype, mountflags, data);
}
int umount(const char *target)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Umount == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Umount(target);
}
int umount2(const char *target, int flag)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Umount2 == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Umount2(target, flag);
}
int open(const char *path, int oflag, ...)
{
#ifdef LOSCFG_RANDOM_DEV
unsigned flags = O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_LARGEFILE | O_TRUNC | O_EXCL | O_DIRECTORY;
if ((unsigned)oflag & ~flags) {
errno = EINVAL;
return FS_FAILURE;
}
size_t pathLen = strlen(path) + 1;
char *canonicalPath = (char *)malloc(pathLen);
if (!canonicalPath) {
errno = ENOMEM;
return FS_FAILURE;
}
if (GetCanonicalPath(NULL, path, canonicalPath, pathLen) == 0) {
FREE_AND_SET_NULL(canonicalPath);
errno = ENOMEM;
return FS_FAILURE;
}
if (strcmp(canonicalPath, RANDOM_DEV_PATH) == 0) {
FREE_AND_SET_NULL(canonicalPath);
if ((O_ACCMODE & (unsigned)oflag) != O_RDONLY) {
errno = EPERM;
return FS_FAILURE;
}
if ((unsigned)oflag & O_DIRECTORY) {
errno = ENOTDIR;
return FS_FAILURE;
}
return RANDOM_DEV_FD;
}
if (strcmp(canonicalPath, "/") == 0 || strcmp(canonicalPath, "/dev") == 0) {
FREE_AND_SET_NULL(canonicalPath);
if ((unsigned)oflag & O_DIRECTORY) {
errno = EPERM;
return FS_FAILURE;
}
errno = EISDIR;
return FS_FAILURE;
}
FREE_AND_SET_NULL(canonicalPath);
#endif
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Open == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Open(path, oflag);
}
int close(int fd)
{
#ifdef LOSCFG_RANDOM_DEV
if (fd == RANDOM_DEV_FD) {
return FS_SUCCESS;
}
#endif
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return closesocket(fd);
}
#endif
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Close == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Close(fd);
}
ssize_t read(int fd, void *buf, size_t nbyte)
{
#ifdef LOSCFG_RANDOM_DEV
if (fd == RANDOM_DEV_FD) {
if (nbyte == 0) {
return FS_SUCCESS;
}
if (buf == NULL) {
errno = EINVAL;
return FS_FAILURE;
}
if (nbyte > 1024) {
nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */
}
struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte};
if (hks_generate_random(&key) != 0) {
errno = EIO;
return FS_FAILURE;
}
return (ssize_t)nbyte;
}
#endif
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return recv(fd, buf, nbyte, 0);
}
#endif
if (g_fs->fsFops == NULL || g_fs->fsFops->Read == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
return g_fs->fsFops->Read(fd, buf, nbyte);
}
ssize_t write(int fd, const void *buf, size_t nbyte)
{
#ifdef LOSCFG_RANDOM_DEV
if (fd == RANDOM_DEV_FD) {
errno = EBADF; /* "/dev/random" is readonly */
return FS_FAILURE;
}
#endif
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return send(fd, buf, nbyte, 0);
}
#endif
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Write == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Write(fd, buf, nbyte);
}
off_t lseek(int fd, off_t offset, int whence)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Seek == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Seek(fd, offset, whence);
}
int unlink(const char *path)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Unlink == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Unlink(path);
}
int fstat(int fd, struct stat *buf)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Fstat == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Fstat(fd, buf);
}
int stat(const char *path, struct stat *buf)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Getattr == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Getattr(path, buf);
}
int fsync(int fd)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Fsync == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Fsync(fd);
}
int mkdir(const char *path, mode_t mode)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Mkdir == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Mkdir(path, mode);
}
DIR *opendir(const char *dirName)
{
if (g_fs == NULL) {
errno = ENODEV;
return NULL;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Opendir == NULL) {
errno = ENOSYS;
return NULL;
}
return g_fs->fsFops->Opendir(dirName);
}
struct dirent *readdir(DIR *dir)
{
if (g_fs == NULL) {
errno = ENODEV;
return NULL;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Readdir == NULL) {
errno = ENOSYS;
return NULL;
}
return g_fs->fsFops->Readdir(dir);
}
int closedir(DIR *dir)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Closedir == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Closedir(dir);
}
int rmdir(const char *path)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Rmdir == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Rmdir(path);
}
int rename(const char *oldName, const char *newName)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Rename == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Rename(oldName, newName);
}
int statfs(const char *path, struct statfs *buf)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Statfs == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Statfs(path, buf);
}
int ftruncate(int fd, off_t length)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Ftruncate == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Ftruncate(fd, length);
}
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _FS_OPERATIONS_H_
#define _FS_OPERATIONS_H_
#include "fcntl.h"
#include "dirent.h"
#include "unistd.h"
#include "sys/mount.h"
#include "sys/stat.h"
#include "sys/statfs.h"
#define FS_SUCCESS 0
#define FS_FAILURE (-1)
#define MAX_FILESYSTEM_LEN 2
struct MountOps {
int (*Mount)(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,
const void *data);
int (*Umount)(const char* target);
int (*Umount2)(const char* target, int flag);
int (*Statfs)(const char *path, struct statfs *buf);
};
struct FsMap {
const char *fileSystemtype;
const struct MountOps *fsMops;
const struct FileOps *fsFops;
};
struct FileOps {
int (*Open)(const char *path, int openFlag, ...);
int (*Close)(int fd);
int (*Unlink)(const char *fileName);
int (*Rmdir)(const char *dirName);
int (*Mkdir)(const char *dirName, mode_t mode);
struct dirent *(*Readdir)(DIR *dir);
DIR *(*Opendir)(const char *dirName);
int (*Closedir)(DIR *dir);
int (*Read)(int fd, void *buf, size_t len);
int (*Write)(int fd, const void *buf, size_t len);
off_t (*Seek)(int fd, off_t offset, int whence);
int (*Getattr)(const char *path, struct stat *buf);
int (*Rename)(const char *oldName, const char *newName);
int (*Fsync)(int fd);
int (*Fstat)(int fd, struct stat *buf);
int (*Stat)(const char *path, struct stat *buf);
int (*Ftruncate)(int fd, off_t length);
};
#endif /* _FS_OPERATIONS_H_ */
@@ -0,0 +1,49 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("littlefs") {
sources = [
"lfs_api.c",
"//third_party/littlefs/lfs.c",
"//third_party/littlefs/lfs_util.c",
]
include_dirs = [
"../../../kernel/arch/include",
"../../../kernel/include",
"../../../utils",
"../../../kal/cmsis",
"../../../kal/posix/include",
"./",
"../",
"//third_party/littlefs",
]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
@@ -0,0 +1,769 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#define _GNU_SOURCE 1
#include "lfs_api.h"
#include "los_config.h"
#include "securec.h"
lfs_t g_lfs;
FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0};
struct FileOpInfo g_fsOp[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
static LittleFsHandleStruct g_handle[LITTLE_FS_MAX_OPEN_FILES] = {0};
struct dirent g_nameValue;
static pthread_mutex_t g_FslocalMutex = PTHREAD_MUTEX_INITIALIZER;
static const char *g_littlefsMntName[LOSCFG_LFS_MAX_MOUNT_SIZE] = {"/a","/b","/c"};
LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) {
if (g_handle[i].useFlag == 0) {
*fd = i;
g_handle[i].useFlag = 1;
g_handle[i].pathName = strdup(fileName);
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_handle[i]);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
*fd = INVALID_FD;
return NULL;
}
static void LfsFreeFd(int fd)
{
pthread_mutex_lock(&g_FslocalMutex);
g_handle[fd].useFlag = 0;
if (g_handle[fd].pathName != NULL) {
free((void *)g_handle[fd].pathName);
g_handle[fd].pathName = NULL;
}
if (g_handle[fd].lfsHandle != NULL) {
g_handle[fd].lfsHandle = NULL;
}
pthread_mutex_unlock(&g_FslocalMutex);
}
BOOL CheckFileIsOpen(const char *fileName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) {
if (g_handle[i].useFlag == 1) {
if (strcmp(g_handle[i].pathName, fileName) == 0) {
pthread_mutex_unlock(&g_FslocalMutex);
return TRUE;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return FALSE;
}
static BOOL LfsFdIsValid(int fd)
{
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) {
return FALSE;
}
if (g_handle[fd].lfsHandle == NULL) {
return FALSE;
}
return TRUE;
}
FileDirInfo *GetFreeDir(const char *dirName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
if (g_lfsDir[i].useFlag == 0) {
g_lfsDir[i].useFlag = 1;
g_lfsDir[i].dirName = strdup(dirName);
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_lfsDir[i]);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return NULL;
}
void FreeDirInfo(const char *dirName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
if (g_lfsDir[i].useFlag == 1 && strcmp(g_lfsDir[i].dirName, dirName) == 0) {
g_lfsDir[i].useFlag = 0;
if (g_lfsDir[i].dirName) {
free(g_lfsDir[i].dirName);
g_lfsDir[i].dirName = NULL;
}
pthread_mutex_unlock(&g_FslocalMutex);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
}
BOOL CheckDirIsOpen(const char *dirName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
if (g_lfsDir[i].useFlag == 1) {
if (strcmp(g_lfsDir[i].dirName, dirName) == 0) {
pthread_mutex_unlock(&g_FslocalMutex);
return TRUE;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return FALSE;
}
int GetFirstLevelPathLen(const char *pathName)
{
int len = 1;
for (int i = 1; i < strlen(pathName) + 1; i++) {
if (pathName[i] == '/') {
break;
}
len++;
}
return len;
}
BOOL CheckPathIsMounted(const char *pathName, struct FileOpInfo **fileOpInfo)
{
char tmpName[LITTLEFS_MAX_LFN_LEN] = {0};
int len = GetFirstLevelPathLen(pathName);
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 1) {
(void)strncpy_s(tmpName, LITTLEFS_MAX_LFN_LEN, pathName, len);
if (strcmp(tmpName, g_fsOp[i].dirName) == 0) {
*fileOpInfo = &(g_fsOp[i]);
pthread_mutex_unlock(&g_FslocalMutex);
return TRUE;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return FALSE;
}
struct FileOpInfo *AllocMountRes(const char* target, const struct FileOps *fileOps)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 0 && strcmp(target, g_littlefsMntName[i]) == 0) {
g_fsOp[i].useFlag = 1;
g_fsOp[i].fsVops = fileOps;
g_fsOp[i].dirName = strdup(target);
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_fsOp[i]);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return NULL;
}
int SetDefaultMountPath(int pathNameIndex, const char* target)
{
if (pathNameIndex >= LOSCFG_LFS_MAX_MOUNT_SIZE) {
return VFS_ERROR;
}
pthread_mutex_lock(&g_FslocalMutex);
g_littlefsMntName[pathNameIndex] = strdup(target);
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_OK;
}
struct FileOpInfo *GetMountRes(const char *target, int *mountIndex)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 1) {
if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
*mountIndex = i;
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_fsOp[i]);
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return NULL;
}
int FreeMountResByIndex(int mountIndex)
{
if (mountIndex < 0 || mountIndex >= LOSCFG_LFS_MAX_MOUNT_SIZE) {
return VFS_ERROR;
}
pthread_mutex_lock(&g_FslocalMutex);
if (g_fsOp[mountIndex].useFlag == 1 && g_fsOp[mountIndex].dirName != NULL) {
g_fsOp[mountIndex].useFlag = 0;
free(g_fsOp[mountIndex].dirName);
g_fsOp[mountIndex].dirName = NULL;
}
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_OK;
}
int FreeMountRes(const char *target)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 1) {
if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
g_fsOp[i].useFlag = 0;
free(g_fsOp[i].dirName);
g_fsOp[i].dirName = NULL;
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_OK;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_ERROR;
}
static int ConvertFlagToLfsOpenFlag (int oflags)
{
int lfsOpenFlag = 0;
if (oflags & O_CREAT) {
lfsOpenFlag |= LFS_O_CREAT;
}
if (oflags & O_EXCL) {
lfsOpenFlag |= LFS_O_EXCL;
}
if (oflags & O_TRUNC) {
lfsOpenFlag |= LFS_O_TRUNC;
}
if (oflags & O_APPEND) {
lfsOpenFlag |= LFS_O_APPEND;
}
if (oflags & O_RDWR) {
lfsOpenFlag |= LFS_O_RDWR;
}
if (oflags & O_WRONLY) {
lfsOpenFlag |= LFS_O_WRONLY;
}
if (oflags & O_RDONLY) {
lfsOpenFlag |= LFS_O_RDONLY;
}
return lfsOpenFlag;
}
static int LittlefsErrno(int result)
{
return (result < 0) ? -result : result;
}
const struct MountOps g_lfsMnt = {
.Mount = LfsMount,
.Umount = LfsUmount,
};
const struct FileOps g_lfsFops = {
.Mkdir = LfsMkdir,
.Unlink = LfsUnlink,
.Rmdir = LfsRmdir,
.Opendir = LfsOpendir,
.Readdir = LfsReaddir,
.Closedir = LfsClosedir,
.Open = LfsOpen,
.Close = LfsClose,
.Write = LfsWrite,
.Read = LfsRead,
.Seek = LfsSeek,
.Rename = LfsRename,
.Getattr = LfsStat,
.Fsync = LfsFsync,
};
int LfsMount(const char *source, const char *target, const char *fileSystemType, unsigned long mountflags,
const void *data)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (target == NULL || fileSystemType == NULL || data == NULL) {
errno = EFAULT;
ret = VFS_ERROR;
goto errout;
}
if (strcmp(fileSystemType, "littlefs") != 0) {
errno = ENODEV;
ret = VFS_ERROR;
goto errout;
}
if (CheckPathIsMounted(target, &fileOpInfo)) {
errno = EBUSY;
ret = VFS_ERROR;
goto errout;
}
// select free mount resource
fileOpInfo = AllocMountRes(target, &g_lfsFops);
if (fileOpInfo == NULL) {
errno = ENODEV;
ret = VFS_ERROR;
goto errout;
}
ret = lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
if (ret != 0) {
ret = lfs_format(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
if (ret == 0) {
ret = lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
}
}
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
errout:
return ret;
}
int LfsUmount(const char *target)
{
int ret;
int mountIndex = -1;
struct FileOpInfo *fileOpInfo = NULL;
if (target == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
fileOpInfo = GetMountRes(target, &mountIndex);
if (fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_unmount(&(fileOpInfo->lfsInfo));
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
(void)FreeMountResByIndex(mountIndex);
return ret;
}
int LfsUnlink(const char *fileName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (fileName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(fileName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_remove(&(fileOpInfo->lfsInfo), fileName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsMkdir(const char *dirName, mode_t mode)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (dirName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_mkdir(&(fileOpInfo->lfsInfo), dirName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsRmdir(const char *dirName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (dirName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_remove(&(fileOpInfo->lfsInfo), dirName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
DIR *LfsOpendir(const char *dirName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (dirName == NULL) {
errno = EFAULT;
goto errout;
}
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
goto errout;
}
if (CheckDirIsOpen(dirName)) {
errno = EBUSY;
goto errout;
}
FileDirInfo *dirInfo = GetFreeDir(dirName);
if (dirInfo == NULL) {
errno = ENFILE;
goto errout;
}
ret = lfs_dir_open(&(fileOpInfo->lfsInfo), (lfs_dir_t *)(&(dirInfo->dir)), dirName);
if (ret != 0) {
FreeDirInfo(dirName);
errno = LittlefsErrno(ret);
goto errout;
}
dirInfo->lfsHandle = &(fileOpInfo->lfsInfo);
return (DIR *)dirInfo;
errout:
return NULL;
}
struct dirent *LfsReaddir(DIR *dir)
{
int ret;
struct lfs_info lfsInfo;
FileDirInfo *dirInfo = (FileDirInfo *)dir;
if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
errno = EBADF;
return NULL;
}
ret = lfs_dir_read(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)), &lfsInfo);
if (ret == TRUE) {
pthread_mutex_lock(&g_FslocalMutex);
(void)strncpy_s(g_nameValue.d_name, sizeof(g_nameValue.d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
if (lfsInfo.type == LFS_TYPE_DIR) {
g_nameValue.d_type = DT_DIR;
} else if (lfsInfo.type == LFS_TYPE_REG) {
g_nameValue.d_type = DT_REG;
}
g_nameValue.d_reclen = lfsInfo.size;
pthread_mutex_unlock(&g_FslocalMutex);
return &g_nameValue;
}
if (ret != 0) {
errno = LittlefsErrno(ret);
}
return NULL;
}
int LfsClosedir(DIR *dir)
{
int ret;
FileDirInfo *dirInfo = (FileDirInfo *)dir;
if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_dir_close(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)));
FreeDirInfo(dirInfo->dirName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsOpen(const char *pathName, int openFlag, int mode)
{
int fd = INVALID_FD;
int err = INVALID_FD;
struct FileOpInfo *fileOpInfo = NULL;
if (pathName == NULL) {
errno = EFAULT;
goto errout;
}
if (CheckPathIsMounted(pathName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
goto errout;
}
// if file is already open, return invalid fd
if (CheckFileIsOpen(pathName)) {
errno = EBUSY;
goto errout;
}
LittleFsHandleStruct *fsHandle = LfsAllocFd(pathName, &fd);
if (fd == INVALID_FD) {
errno = ENFILE;
goto errout;
}
int lfsOpenFlag = ConvertFlagToLfsOpenFlag(openFlag);
err = lfs_file_open(&(fileOpInfo->lfsInfo), &(fsHandle->file), pathName, lfsOpenFlag);
if (err != 0) {
LfsFreeFd(fd);
errno = LittlefsErrno(err);
goto errout;
}
g_handle[fd].lfsHandle = &(fileOpInfo->lfsInfo);
return fd;
errout:
return INVALID_FD;
}
int LfsRead(int fd, void *buf, unsigned int len)
{
int ret;
if (buf == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_file_read(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
if (ret < 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsWrite(int fd, const void *buf, unsigned int len)
{
int ret;
if (buf == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_file_write(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
if (ret < 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
off_t LfsSeek(int fd, off_t offset, int whence)
{
off_t ret;
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, whence);
if (ret < 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsClose(int fd)
{
int ret;
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
pthread_mutex_lock(&g_FslocalMutex);
ret = lfs_file_close(g_handle[fd].lfsHandle, &(g_handle[fd].file));
pthread_mutex_unlock(&g_FslocalMutex);
LfsFreeFd(fd);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsRename(const char *oldName, const char *newName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (oldName == NULL || newName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(oldName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_rename(&(fileOpInfo->lfsInfo), oldName, newName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsStat(const char *path, struct stat *buf)
{
int ret;
struct lfs_info info;
struct FileOpInfo *fileOpInfo = NULL;
if (path == NULL || buf == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(path, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_stat(&(fileOpInfo->lfsInfo), path, &info);
if (ret == 0) {
buf->st_size = info.size;
} else {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsFsync(int fd)
{
int ret;
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_file_sync(g_handle[fd].lfsHandle, &(g_handle[fd].file));
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LFS_API_H_
#define _LFS_API_H_
#include "bits/alltypes.h"
#include "fcntl.h"
#include "sys/stat.h"
#include "dirent.h"
#include "errno.h"
#include "fs_operations.h"
#include "lfs.h"
#include "lfs_util.h"
#include "memory.h"
#include "pthread.h"
#define INVALID_FD (-1)
typedef unsigned mode_t;
#ifndef VFS_ERROR
#define VFS_ERROR (-1)
#endif
#ifndef VFS_OK
#define VFS_OK 0
#endif
typedef struct {
uint8_t useFlag;
const char *pathName;
lfs_t *lfsHandle;
lfs_file_t file;
} LittleFsHandleStruct;
struct FileOpInfo {
uint8_t useFlag;
const struct FileOps *fsVops;
char *dirName;
lfs_t lfsInfo;
};
typedef struct {
uint8_t useFlag;
char *dirName;
lfs_t *lfsHandle;
lfs_dir_t dir;
} FileDirInfo;
#define LITTLE_FS_MAX_OPEN_FILES 100
#define LITTLE_FS_STANDARD_NAME_LENGTH 50
#define LITTLE_FS_MAX_NAME_LEN 255
#define MAX_DEF_BUF_NUM 21
#define MAX_BUFFER_LEN 100
#define MAX_WRITE_FILE_LEN 500
#define MAX_READ_FILE_LEN 500
#define LITTLEFS_MAX_LFN_LEN 255
#ifndef LFS_MAX_OPEN_DIRS
#define LFS_MAX_OPEN_DIRS 10
#endif
LittleFsHandleStruct *GetFreeFd(int *fd);
int InitMountInfo(const char *fileSystemType, const struct MountOps *fsMops);
int LfsMount(const char *source, const char *target, const char *fileSystemType, unsigned long mountflags,
const void *data);
int LfsUmount(const char *target);
int LfsUnlink(const char *fileName);
int LfsMkdir(const char *dirName, mode_t mode);
int LfsRmdir(const char *dirName);
DIR *LfsOpendir(const char *dirName);
struct dirent *LfsReaddir(DIR *dir);
int LfsClosedir(DIR *dir);
int LfsOpen(const char *pathName, int openFlag, int mode);
int LfsRead(int fd, void *buf, unsigned int len);
int LfsWrite(int fd, const void *buf, unsigned int len);
off_t LfsSeek(int fd, off_t offset, int whence);
int LfsClose(int fd);
int LfsRename(const char *oldName, const char *newName);
int LfsStat(const char *path, struct stat *buf);
int LfsFsync(int fd);
int SetDefaultMountPath(int pathNameIndex, const char* target);
const struct FsMap *MountFindfs(const char *filesystemtype);
#endif /* _LFS_API_H_ */
@@ -0,0 +1,50 @@
# Copyright (c) 2021-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
import("lwip_porting.gni")
import("//third_party/lwip/lwip.gni")
config("lwip_depends") {
defines = [ "_BSD_SOURCE = 1" ]
}
static_library("lwip") {
include_dirs = [
"//kernel/liteos_m/kal/posix/include",
"//kernel/liteos_m/kernel/arch/include",
]
include_dirs += LWIP_PORTING_INCLUDE_DIRS
include_dirs += LWIP_INCLUDE_DIRS
sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES
configs += [ ":lwip_depends" ]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
@@ -0,0 +1,178 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include <lwip/sys.h>
#include <lwip/etharp.h>
#include <lwip/netifapi.h>
#include <lwip/priv/api_msg.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, ERR_MEM)
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
static struct netif *netif_find_by_name(const char *name)
{
struct netif *netif = NULL;
LWIP_ASSERT_CORE_LOCKED();
if (name == NULL) {
return NULL;
}
NETIF_FOREACH(netif) {
if (strcmp("lo", name) == 0 && (netif->name[0] == 'l' && netif->name[1] == 'o')) {
LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found lo\n"));
return netif;
}
if (strcmp(netif->full_name, name) == 0) {
LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found %s\n", name));
return netif;
}
}
LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: didn't find %s\n", name));
return NULL;
}
static err_t netifapi_do_find_by_name(struct tcpip_api_call_data *m)
{
/* cast through void* to silence alignment warnings.
* We know it works because the structs have been instantiated as struct netifapi_msg */
struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
msg->netif = netif_find_by_name(msg->msg.ifs.name);
return ERR_OK;
}
struct netif *netifapi_netif_find_by_name(const char *name)
{
struct netif *netif = NULL;
NETIFAPI_VAR_DECLARE(msg);
NETIFAPI_VAR_ALLOC(msg);
NETIFAPI_VAR_REF(msg).netif = NULL;
#if LWIP_MPU_COMPATIBLE
if (strncpy_s(NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE, name, NETIF_NAMESIZE - 1)) {
NETIFAPI_VAR_FREE(msg);
return netif;
}
NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0';
#else
NETIFAPI_VAR_REF(msg).msg.ifs.name = (char *)name;
#endif /* LWIP_MPU_COMPATIBLE */
(void)tcpip_api_call(netifapi_do_find_by_name, &API_VAR_REF(msg).call);
netif = msg.netif;
NETIFAPI_VAR_FREE(msg);
return netif;
}
#if LWIP_IPV6
int ip6addr_aton(const char *cp, ip6_addr_t *addr)
{
const int ipv6_blocks = 8;
u16_t current_block_index = 0;
u16_t current_block_value = 0;
u16_t addr16[ipv6_blocks];
u16_t *a16 = (u16_t *)addr->addr;
int squash_pos = ipv6_blocks;
int i;
const char *sc = cp;
const char *ss = cp-1;
for (; ; sc++) {
if (current_block_index >= ipv6_blocks) {
return 0; // address too long
}
if (*sc == 0) {
if (sc - ss == 1) {
if (squash_pos != current_block_index) {
return 0; // empty address or address ends with a single ':'
} // else address ends with one valid "::"
} else {
addr16[current_block_index++] = current_block_value;
}
break;
} else if (*sc == ':') {
if (sc - ss == 1) {
if (sc != cp || sc[1] != ':') {
return 0; // address begins with a single ':' or contains ":::"
} // else address begins with one valid "::"
} else {
addr16[current_block_index++] = current_block_value;
}
if (sc[1] == ':') {
if (squash_pos != ipv6_blocks) {
return 0; // more than one "::"
}
squash_pos = current_block_index;
sc++;
}
ss = sc; // ss points to the recent ':' position
current_block_value = 0;
} else if (lwip_isxdigit(*sc) && (sc - ss) < 5) { // 4 hex-digits at most
current_block_value = (current_block_value << 4) +
(*sc | ('a' - 'A')) - '0' - ('a' - '9' - 1) * (*sc >= 'A');
#if LWIP_IPV4
} else if (*sc == '.' && current_block_index < ipv6_blocks - 1) {
ip4_addr_t ip4;
int ret = ip4addr_aton(ss+1, &ip4);
if (!ret) {
return 0;
}
ip4.addr = lwip_ntohl(ip4.addr);
addr16[current_block_index++] = (u16_t)(ip4.addr >> 16);
addr16[current_block_index++] = (u16_t)(ip4.addr);
break;
#endif /* LWIP_IPV4 */
} else {
return 0; // unexpected char or too many digits
}
}
if (squash_pos == ipv6_blocks && current_block_index != ipv6_blocks) {
return 0; // address too short
}
if (squash_pos != ipv6_blocks && current_block_index == ipv6_blocks) {
return 0; // unexpected "::" in address
}
for (i = 0; i < squash_pos; ++i) {
a16[i] = lwip_htons(addr16[i]);
}
for (; i < ipv6_blocks - current_block_index + squash_pos; ++i) {
a16[i] = 0;
}
for (; i < ipv6_blocks; ++i) {
a16[i] = lwip_htons(addr16[i - ipv6_blocks + current_block_index]);
}
return 1;
}
#endif /* LWIP_IPV6 */
@@ -0,0 +1,41 @@
# Copyright (c) 2021-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
LWIP_PORTING_DIR = "//kernel/liteos_m/components/net/lwip-2.1"
LWIP_PORTING_INCLUDE_DIRS = [ "$LWIP_PORTING_DIR/porting/include" ]
LWIP_PORTING_FILES = [
"$LWIP_PORTING_DIR/porting/src/driverif.c",
"$LWIP_PORTING_DIR/porting/src/lwip_init.c",
"$LWIP_PORTING_DIR/porting/src/netdb_porting.c",
"$LWIP_PORTING_DIR/porting/src/sockets_porting.c",
"$LWIP_PORTING_DIR/porting/src/sys_arch.c",
"$LWIP_PORTING_DIR/enhancement/src/fixme.c",
]
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_CC_H_
#define _LWIP_PORTING_CC_H_
#ifdef LITTLE_ENDIAN
#undef LITTLE_ENDIAN
#endif
#ifdef BIG_ENDIAN
#undef BIG_ENDIAN
#endif
#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include "securec.h"
#include "memory_pool.h"
#ifdef htons
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
#endif
#define SOCKLEN_T_DEFINED
#define SA_FAMILY_T_DEFINED
#define IN_PORT_T_DEFINED
#define LWIP_TIMEVAL_PRIVATE 0
#define LWIP_ERRNO_STDINCLUDE
#define LWIP_SOCKET_STDINCLUDE
#define LWIP_DNS_API_DEFINE_ERRORS 0
#define LWIP_DNS_API_DEFINE_FLAGS 0
#define LWIP_DNS_API_DECLARE_STRUCTS 0
#define LWIP_DNS_API_DECLARE_H_ERRNO 0
#ifndef __SIZEOF_POINTER__
#define __SIZEOF_POINTER__ 4 // 32 bit system
#endif
#define LOS_TASK_STATUS_DETACHED 0x0100 // reserved
#if defined(__arm__) && defined(__ARMCC_VERSION)
/* Keil uVision4 tools */
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(fld) fld
#define ALIGNED(n) __align(n)
#elif defined (__IAR_SYSTEMS_ICC__)
/* IAR Embedded Workbench tools */
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(fld) fld
// #error NEEDS ALIGNED
#else
/* GCC tools (CodeSourcery) */
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(fld) fld
#define ALIGNED(n) __attribute__((aligned (n)))
#endif
#define LWIP_RAND rand
extern void HilogPrintf(const char *fmt, ...);
#ifndef HILOG_INFO
#define HILOG_INFO(...)
#ifndef HILOG_MODULE_APP
#define HILOG_MODULE_APP 0
#endif
#endif
#ifndef HILOG_ERROR
#define HILOG_ERROR(...)
#endif
#define LWIP_PLATFORM_DIAG(vars) HilogPrintf vars
#define LWIP_PLATFORM_ASSERT(x) do {HILOG_ERROR(HILOG_MODULE_APP, \
"Assertion \"%s\" errno %d line %d in %s\n", \
x, errno, __LINE__, __FILE__);} while (0)
#define mem_clib_malloc LWIP_MEM_ALLOC
#define mem_clib_free LWIP_MEM_FREE
#define mem_clib_calloc LWIP_MEM_CALLOC
#define init_waitqueue_head(...)
#define poll_check_waiters(...)
#define IOCTL_CMD_CASE_HANDLER()
#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.114.114")))
#define DNS_SERVER_ADDRESS_SECONDARY(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.115.115")))
#endif /* _LWIP_PORTING_CC_H_ */
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_PERF_H_
#define _LWIP_PORTING_PERF_H_
#if LWIP_PERF
#define PERF_START do { /* something to do */ } while (0)
#define PERF_STOP(x) do { /* something to do */ } while (0)
#endif
#endif /* _LWIP_PORTING_PERF_H_ */
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_SYS_ARCH_H_
#define _LWIP_PORTING_SYS_ARCH_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Mutex
*/
typedef uint32_t sys_mutex_t;
/**
* Semaphore
*/
typedef uint32_t sys_sem_t;
/**
* MessageBox
*/
typedef uint32_t sys_mbox_t;
/**
* Protector
*/
typedef void *sys_prot_t;
/**
* Thread
*/
typedef uint32_t sys_thread_t;
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_SYS_ARCH_H_ */
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_INET_H_
#define _LWIP_PORTING_INET_H_
#include <arpa/inet.h>
#include <netinet/in.h>
#include_next <lwip/inet.h>
#if LWIP_IPV4
#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) \
((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) \
(ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
/* directly map this to the lwip internal functions */
#define inet_addr(cp) ipaddr_addr(cp)
#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)
#define inet_ntoa(addr) ip4addr_ntoa((const ip4_addr_t*)&(addr))
#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) \
{(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
(target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
(target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
(target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) \
{(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
(target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
(target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
(target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3]; \
ip6_addr_clear_zone(target_ip6addr);}
#endif /* LWIP_IPV6 */
#endif /* _LWIP_PORTING_INET_H_ */
@@ -0,0 +1,298 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_LWIPOPTS_H_
#define _LWIP_PORTING_LWIPOPTS_H_
// lwIP debug options, comment the ones you don't want
#define LWIP_DEBUG 0
#if LWIP_DEBUG
#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define IGMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define DRIVERIF_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TIMERS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_ERR_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_SACK_DEBUG LWIP_DBG_OFF
#define TCP_TLP_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF
#define AUTOIP_DEBUG LWIP_DBG_OFF
#define DNS_DEBUG LWIP_DBG_OFF
#define TFTP_DEBUG LWIP_DBG_OFF
#define SYS_ARCH_DEBUG LWIP_DBG_OFF
#define SNTP_DEBUG LWIP_DBG_OFF
#define IP6_DEBUG LWIP_DBG_OFF
#define DHCP6_DEBUG LWIP_DBG_OFF
#define DRV_STS_DEBUG LWIP_DBG_OFF
#endif
// Options only in new opt.h
#define LWIP_SOCKET_SELECT 0
#define LWIP_SOCKET_POLL 1
// Options in old opt.h that differs from new opt.h
#define MEM_ALIGNMENT __SIZEOF_POINTER__
#define MEMP_NUM_NETDB 8
#define IP_REASS_MAXAGE 3
#define IP_SOF_BROADCAST 1
#define IP_SOF_BROADCAST_RECV 1
#define LWIP_MULTICAST_PING 1
#define LWIP_RAW 1
#define LWIP_DHCP_AUTOIP_COOP_TRIES 64
#define TCP_LISTEN_BACKLOG 1
#define TCP_DEFAULT_LISTEN_BACKLOG 16
#define LWIP_WND_SCALE 1
#define TCP_RCV_SCALE 7
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define LWIP_NETCONN_FULLDUPLEX 1 // Caution
#define LWIP_COMPAT_SOCKETS 2
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
#define LWIP_TCP_KEEPALIVE 1
#define RECV_BUFSIZE_DEFAULT 65535
#define SO_REUSE_RXTOALL 1
#define LWIP_CHECKSUM_ON_COPY 1
#define LWIP_IPV6 1
#define LWIP_IPV6_NUM_ADDRESSES 5
#define LWIP_ND6_NUM_PREFIXES 10
#define LWIP_IPV6_DHCP6 1
#define LWIP_IPV6_DHCP6_STATEFUL 1
// Options in old lwipopts.h
#define ARP_QUEUEING 1
#define DEFAULT_ACCEPTMBOX_SIZE 32
#define DEFAULT_RAW_RECVMBOX_SIZE 128
#define DEFAULT_TCP_RECVMBOX_SIZE 128
#define DEFAULT_UDP_RECVMBOX_SIZE 128
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
#define ETH_PAD_SIZE 2
#define IP_REASS_MAX_PBUFS (((65535) / (IP_FRAG_MAX_MTU - 20 - 8) + 1) * MEMP_NUM_REASSDATA)
#define LWIP_COMPAT_SOCKETS 2
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF
#define LWIP_DHCP 1
#define LWIP_DNS 1
#define LWIP_ETHERNET 1
#define LWIP_HAVE_LOOPIF 1
#define LWIP_IGMP 1
#define LWIP_NETIF_API 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
#define LWIP_RAW 1
#define LWIP_SOCKET_OFFSET FAT_MAX_OPEN_FILES
#define LWIP_SO_RCVBUF 1
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_SNDTIMEO 1
#define LWIP_STATS_DISPLAY 1
#define MEM_LIBC_MALLOC 1
#define MEMP_NUM_ARP_QUEUE (65535 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8))
#define MEMP_NUM_NETBUF (65535 * 3 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8))
#define MEMP_NUM_NETCONN LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_PBUF LWIP_CONFIG_NUM_SOCKETS*2
#define MEMP_NUM_RAW_PCB LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_REASSDATA (IP_REASS_MAX_MEM_SIZE / 65535)
#define MEMP_NUM_TCPIP_MSG_API 64
#define MEMP_NUM_TCPIP_MSG_INPKT 512
#define MEMP_NUM_TCP_PCB LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_TCP_PCB_LISTEN LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_TCP_SEG (((TCP_SND_BUF * 3 / 2) + TCP_WND) * LWIP_CONFIG_NUM_SOCKETS / TCP_MSS)
#define MEMP_NUM_UDP_PCB LWIP_CONFIG_NUM_SOCKETS
#define MEM_SIZE (4*1024*1024) // (512*1024)
#define PBUF_POOL_BUFSIZE 1550
#define PBUF_POOL_SIZE 64
#define SO_REUSE 1
#define TCPIP_MBOX_SIZE 512
#define TCPIP_THREAD_PRIO 5
#define TCPIP_THREAD_STACKSIZE 0x6000
#define TCP_MAXRTX 64
#define TCP_MSS 1400
#define TCP_SND_BUF 65535
#define TCP_SND_QUEUELEN (8 * TCP_SND_BUF) / TCP_MSS
#define TCP_TTL 255
#define TCP_WND 32768
#define UDP_TTL 255
// Options in old lwipopts.h but kept in Defaults with new opt.h
#define IP_FORWARD 0
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_ICMP 1
#define LWIP_NETCONN 1
#define LWIP_SOCKET 1
#define LWIP_STATS 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define NO_SYS 0
#define TCP_QUEUE_OOSEQ LWIP_TCP
// Change some options for lwIP 2.1.2
#undef TCP_MAXRTX
#define TCP_MAXRTX 12
#undef LWIP_COMPAT_SOCKETS
#define LWIP_COMPAT_SOCKETS 0
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + (LWIP_IPV6 * LWIP_IPV6_DHCP6))
#undef DEFAULT_ACCEPTMBOX_SIZE
#define DEFAULT_ACCEPTMBOX_SIZE LWIP_CONFIG_NUM_SOCKETS
#undef TCP_MSS
#define TCP_MSS (IP_FRAG_MAX_MTU - 20 - 20)
#undef IP_SOF_BROADCAST_RECV
#define IP_SOF_BROADCAST_RECV 0
/**
* Defines whether to enable debugging for driver module.
*/
#ifndef DRIVERIF_DEBUG
#define DRIVERIF_DEBUG LWIP_DBG_OFF
#endif
// Options for old lwipopts.h
#define IP_FRAG_MAX_MTU 1500
#define LWIP_CONFIG_NUM_SOCKETS 128
#define IP_REASS_MAX_MEM_SIZE (MEM_SIZE / 4)
// Options for enhancement code, same for old lwipopts.h
#define LWIP_NETIF_PROMISC 1
#define LWIP_TFTP LOSCFG_NET_LWIP_SACK_TFTP
#define LWIP_DHCPS 1
#define LWIP_ENABLE_NET_CAPABILITY 1
#define LWIP_ENABLE_CAP_NET_BROADCAST 0
// Options for GT
#undef LWIP_NETIF_PROMISC
#define LWIP_NETIF_PROMISC 0
#undef LWIP_ICMP
#define LWIP_ICMP 0
#undef LWIP_DHCP
#define LWIP_DHCP 0
#undef LWIP_IGMP
#define LWIP_IGMP 0
#undef LWIP_IPV6
#define LWIP_IPV6 0
#undef LWIP_IPV6_DHCP6
#define LWIP_IPV6_DHCP6 0
#undef TCP_SND_BUF
#define TCP_SND_BUF (65535 / 3)
#undef TCP_WND
#define TCP_WND ((TCP_SND_BUF * 2) / 3)
#undef TCP_SND_QUEUELEN
#define TCP_SND_QUEUELEN (2 * (TCP_SND_BUF / TCP_MSS))
#undef MEMP_NUM_NETDB
#define MEMP_NUM_NETDB 1
#undef MEMP_NUM_ARP_QUEUE
#define MEMP_NUM_ARP_QUEUE 4
#undef MEMP_NUM_NETBUF
#define MEMP_NUM_NETBUF 12
#undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 32
#undef MEMP_NUM_PBUF
#define MEMP_NUM_PBUF 0
#undef PBUF_POOL_SIZE
#define PBUF_POOL_SIZE 0
#undef MEMP_NUM_RAW_PCB
#define MEMP_NUM_RAW_PCB 8
#undef MEMP_NUM_REASSDATA
#define MEMP_NUM_REASSDATA 12
#undef MEMP_NUM_TCPIP_MSG_API
#define MEMP_NUM_TCPIP_MSG_API 32
#undef MEMP_NUM_TCPIP_MSG_INPKT
#define MEMP_NUM_TCPIP_MSG_INPKT 32
#undef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB 8
#undef MEMP_NUM_TCP_PCB_LISTEN
#define MEMP_NUM_TCP_PCB_LISTEN 4
#undef MEMP_NUM_TCP_SEG
#define MEMP_NUM_TCP_SEG 64
#undef MEMP_NUM_UDP_PCB
#define MEMP_NUM_UDP_PCB 4
#undef TCPIP_THREAD_STACKSIZE
#define TCPIP_THREAD_STACKSIZE 0x1000
#undef LWIP_SOCKET_SELECT
#define LWIP_SOCKET_SELECT 1
// use PBUF_RAM instead of PBUF_POOL in udp_input
#define USE_PBUF_RAM_UDP_INPUT 1
#endif /* _LWIP_PORTING_LWIPOPTS_H_ */
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_NETDB_H_
#define _LWIP_PORTING_NETDB_H_
#include <netdb.h>
#include_next <lwip/netdb.h>
#endif /* _LWIP_PORTING_NETDB_H_ */
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_NETIF_H_
#define _LWIP_PORTING_NETIF_H_
#include <net/if.h>
#include <netinet/ip.h>
#define netif_find netifapi_netif_find_by_name
#if LWIP_DHCPS
#define LWIP_NETIF_CLIENT_DATA_INDEX_DHCP LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, \
LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS
#endif
#define linkoutput linkoutput; \
void (*drv_send)(struct netif *netif, struct pbuf *p); \
u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \
void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \
char full_name[IFNAMSIZ]; \
u16_t link_layer_type
#include_next <lwip/netif.h>
#undef linkoutput
#if LWIP_DHCPS
#undef LWIP_NETIF_CLIENT_DATA_INDEX_DHCP
#endif
#include <lwip/etharp.h>
#ifdef __cplusplus
extern "C" {
#endif
// redefine NETIF_NAMESIZE which was defined in netif.h
#undef NETIF_NAMESIZE
#define NETIF_NAMESIZE IFNAMSIZ
#define LOOPBACK_IF 0
#define ETHERNET_DRIVER_IF 1
#define WIFI_DRIVER_IF 801
#define BT_PROXY_IF 802
err_t driverif_init(struct netif *netif);
void driverif_input(struct netif *netif, struct pbuf *p);
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_NETIF_H_ */
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_NETIFAPI_H_
#define _LWIP_PORTING_NETIFAPI_H_
#include_next <lwip/netifapi.h>
#ifdef __cplusplus
extern "C" {
#endif
err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num);
err_t netifapi_dhcps_stop(struct netif *netif);
#define netifapi_dhcp_cleanup(n) netifapi_netif_common(n, dhcp_cleanup, NULL)
#define netifapi_dhcp_is_bound(n) netifapi_netif_common(n, NULL, dhcp_is_bound)
void netifapi_netif_rmv_ip6_address(struct netif *netif, ip_addr_t *ipaddr);
struct netif *netifapi_netif_find_by_name(const char *name);
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_NETIFAPI_H_ */
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LWIP_PORTING_SOCKETS_H_
#define _LWIP_PORTING_SOCKETS_H_
#include <sys/socket.h>
#include <poll.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <limits.h>
#include <fcntl.h>
#include_next <lwip/sockets.h>
#include <fatfs.h>
#ifdef __cplusplus
extern "C" {
#endif
#if FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
#error "external FD_SETSIZE too small for number of sockets"
#else
#define LWIP_SELECT_MAXNFDS FD_SETSIZE
#endif
#if IOV_MAX > 0xFFFF
#error "IOV_MAX larger than supported by LwIP"
#endif
#if LWIP_UDP && LWIP_UDPLITE
#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
#endif
// For BSD 4.4 socket sa_len compatibility
#define DF_NADDR(addr)
#define SA_LEN(addr, _) (IP_IS_V4_VAL(addr) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
#define sa_len sa_data[0] * 0 + SA_LEN(naddr, _)
#define sin_len sin_zero[0]
#define sin6_len sin6_addr.s6_addr[0]
// for sockets.c, TCP_KEEPALIVE is not supported currently
#define TCP_KEEPALIVE 0xFF
#define SIN_ZERO_LEN 8
int closesocket(int sockfd);
int ioctlsocket(int s, long cmd, void *argp);
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_SOCKETS_H_ */
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef __LITEOS_M_LWIPOPTS_H__
#define __LITEOS_M_LWIPOPTS_H__
// Just redirect
#include "lwip/lwipopts.h"
#endif // __LITEOS_M_LWIPOPTS_H__
@@ -0,0 +1,357 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include <lwip/sys.h>
#include <lwip/netif.h>
#include <lwip/snmp.h>
#include <lwip/etharp.h>
#include <lwip/sockets.h>
#include <lwip/snmp.h>
#include <lwip/etharp.h>
#include <lwip/ethip6.h>
#define LWIP_NETIF_HOSTNAME_DEFAULT "default"
#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 100000000 // 100Mbps
#define link_rx_drop cachehit
#define link_rx_overrun cachehit
#define LWIP_STATIC static
#define NETIF_NAME_PREFIX_MAX_LENGTH 10
#define NETIF_NAME_PREFIX_ETH "eth"
#define NETIF_NAME_PREFIX_WIFI "wlan"
#define NETIF_NAME_PREFIX_BT "bt"
#ifndef LWIP_NETIF_IFINDEX_MAX_EX
#define LWIP_NETIF_IFINDEX_MAX_EX 255
#endif
LWIP_STATIC void driverif_get_ifname_prefix(struct netif *netif, char *prefix, int prefixLen)
{
if (prefix == NULL || netif == NULL) {
LWIP_ASSERT("invalid param", 0);
return;
}
switch (netif->link_layer_type) {
case ETHERNET_DRIVER_IF:
strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_ETH);
break;
case WIFI_DRIVER_IF:
strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_WIFI);
break;
case BT_PROXY_IF:
strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_BT);
break;
default:
LWIP_ASSERT("invalid link_layer_type", 0);
break;
}
}
LWIP_STATIC void driverif_init_ifname(struct netif *netif)
{
struct netif *tmpnetif = NULL;
char prefix[NETIF_NAME_PREFIX_MAX_LENGTH] = {0};
driverif_get_ifname_prefix(netif, prefix, NETIF_NAME_PREFIX_MAX_LENGTH);
netif->name[0] = prefix[0];
netif->name[1] = prefix[1];
if (netif->full_name[0] != '\0') {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("netif already has fullname %s\n", netif->full_name));
return;
}
for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) {
if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1,
"%s%d", prefix, i) < 0) {
break;
}
NETIF_FOREACH(tmpnetif) {
if (strcmp(tmpnetif->full_name, netif->full_name) == 0) {
break;
}
}
if (tmpnetif == NULL) {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("set fullname success %s\n", netif->full_name));
return;
}
}
netif->full_name[0] = '\0';
}
/*
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this driverif
* @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
LWIP_STATIC err_t driverif_output(struct netif *netif, struct pbuf *p)
{
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_output : send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \
(void *)p, p->tot_len, (void *)netif));
#if PF_PKT_SUPPORT
if (all_pkt_raw_pcbs != NULL) {
p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST));
p->flags |= PBUF_FLAG_OUTGOING;
(void)raw_pkt_input(p, netif, NULL);
}
#endif
#if ETH_PAD_SIZE
(void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
netif->drv_send(netif, p);
#if ETH_PAD_SIZE
(void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
void driverif_input_proc(struct netif *netif, struct pbuf *p)
{
u16_t ethhdr_type;
struct eth_hdr *ethhdr = NULL;
err_t ret = ERR_VAL;
ethhdr = (struct eth_hdr *)p->payload;
ethhdr_type = ntohs(ethhdr->type);
switch (ethhdr_type) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_IPV6:
case ETHTYPE_ARP:
#if ETHARP_SUPPORT_VLAN
case ETHTYPE_VLAN:
#endif /* ETHARP_SUPPORT_VLAN */
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdr_type));
/* full packet send to tcpip_thread to process */
if (netif->input != NULL) {
ret = netif->input(p, netif);
}
if (ret != ERR_OK) {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
if (ret == ERR_MEM) {
MIB2_STATS_NETIF_INC(netif, ifinoverruns);
LINK_STATS_INC(link.link_rx_overrun);
}
} else {
LINK_STATS_INC(link.recv);
}
break;
default:
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", \
ethhdr_type));
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
break;
}
}
/*
* This function should be called by network driver to pass the input packet to LwIP.
* Before calling this API, driver has to keep the packet in pbuf structure. Driver has to
* call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver
* has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread.
* Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to
* free the pbuf.
*
* @param netif the lwip network interface structure for this driverif
* @param p packet in pbuf structure format
*/
void driverif_input(struct netif *netif, struct pbuf *p)
{
#if PF_PKT_SUPPORT
#if (DRIVERIF_DEBUG & LWIP_DBG_OFF)
u16_t ethhdr_type;
struct eth_hdr* ethhdr = NULL;
#endif
err_t ret = ERR_VAL;
#endif
LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return);
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \
packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len));
/* points to packet payload, which starts with an Ethernet header */
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
if (p->len < SIZEOF_ETH_HDR) {
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
return;
}
#if PF_PKT_SUPPORT
#if (DRIVERIF_DEBUG & LWIP_DBG_OFF)
ethhdr = (struct eth_hdr *)p->payload;
ethhdr_type = ntohs(ethhdr->type);
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", \
ethhdr_type, netif->input));
#endif
/* full packet send to tcpip_thread to process */
if (netif->input) {
ret = netif->input(p, netif);
}
if (ret != ERR_OK) {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
if (ret == ERR_MEM) {
LINK_STATS_INC(link.link_rx_overrun);
}
} else {
LINK_STATS_INC(link.recv);
}
#else
driverif_input_proc(netif, p);
#endif
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n"));
}
/*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this driverif
* @return ERR_OK if the loopif is initialized
* ERR_MEM on Allocation Failure
* any other err_t on error
*/
err_t driverif_init(struct netif *netif)
{
u16_t link_layer_type;
if (netif == NULL) {
return ERR_IF;
}
link_layer_type = netif->link_layer_type;
LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \
((link_layer_type == ETHERNET_DRIVER_IF) \
|| (link_layer_type == WIFI_DRIVER_IF \
|| link_layer_type == BT_PROXY_IF)), \
return ERR_IF);
LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \
(netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF);
LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF);
#if LWIP_NETIF_PROMISC
LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF);
#endif
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT;
#endif /* LWIP_NETIF_HOSTNAME */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
netif->output = etharp_output;
netif->linkoutput = driverif_output;
/* init the netif's full name */
driverif_init_ifname(netif);
/* maximum transfer unit */
netif->mtu = IP_FRAG_MAX_MTU;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
#if DRIVER_STATUS_CHECK
NETIF_FLAG_DRIVER_RDY |
#endif
#if LWIP_IGMP
NETIF_FLAG_IGMP |
#endif
/**
@page RFC-2710 RFC-2710
@par Compliant Sections
Section 5. Node State Transition Diagram
@par Behavior Description
MLD messages are sent for multicast addresses whose scope is 2
(link-local), including Solicited-Node multicast addresses.\n
Behavior:Stack will send MLD6 report /Done to solicited node multicast address
if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
*/
/* Enable sending MLD report /done for solicited address during neighbour discovery */
#if LWIP_IPV6 && LWIP_IPV6_MLD
#if LWIP_MLD6_ENABLE_MLD_ON_DAD
NETIF_FLAG_MLD6 |
#endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */
#endif
NETIF_FLAG_LINK_UP;
#if DRIVER_STATUS_CHECK
netif->waketime = -1;
#endif /* DRIVER_STATUS_CHECK */
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif));
return ERR_OK;
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "lwip/tcpip.h"
#include "ohos_init.h"
void TcpIpPortingInit()
{
tcpip_init(NULL, NULL);
}
SYSEX_SERVICE_INIT(TcpIpPortingInit);
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip/netdb.h"
#if LWIP_DNS && LWIP_SOCKET
struct hostent *gethostbyname(const char *name)
{
if (name == NULL) {
return NULL;
}
return lwip_gethostbyname(name);
}
int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result,
int *h_errnop)
{
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
}
void freeaddrinfo(struct addrinfo *res)
{
lwip_freeaddrinfo(res);
}
int getaddrinfo(const char *restrict nodename, const char *restrict servname, const struct addrinfo *restrict hints,
struct addrinfo **restrict res)
{
return lwip_getaddrinfo(nodename, servname, hints, res);
}
#endif
@@ -0,0 +1,188 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip/priv/sockets_priv.h"
#include <lwip/sockets.h>
#if !LWIP_COMPAT_SOCKETS
#if LWIP_SOCKET
#define CHECK_NULL_PTR(ptr) do { if ((ptr) == NULL) { set_errno(EFAULT); return -1; } } while (0)
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
return lwip_accept(s, addr, addrlen);
}
int bind(int s, const struct sockaddr *name, socklen_t namelen)
{
CHECK_NULL_PTR(name);
if (namelen < sizeof(*name)) {
set_errno(EINVAL);
return -1;
}
return lwip_bind(s, name, namelen);
}
int shutdown(int s, int how)
{
return lwip_shutdown(s, how);
}
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
{
CHECK_NULL_PTR(name);
CHECK_NULL_PTR(namelen);
return lwip_getpeername(s, name, namelen);
}
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
{
CHECK_NULL_PTR(name);
CHECK_NULL_PTR(namelen);
return lwip_getsockname(s, name, namelen);
}
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
{
return lwip_getsockopt(s, level, optname, optval, optlen);
}
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
{
return lwip_setsockopt(s, level, optname, optval, optlen);
}
int closesocket(int s)
{
return lwip_close(s);
}
int connect(int s, const struct sockaddr *name, socklen_t namelen)
{
CHECK_NULL_PTR(name);
if (namelen < sizeof(*name)) {
set_errno(EINVAL);
return -1;
}
return lwip_connect(s, name, namelen);
}
int listen(int s, int backlog)
{
return lwip_listen(s, backlog);
}
ssize_t recv(int s, void *mem, size_t len, int flags)
{
CHECK_NULL_PTR(mem);
return lwip_recv(s, mem, len, flags);
}
ssize_t recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
CHECK_NULL_PTR(mem);
return lwip_recvfrom(s, mem, len, flags, from, fromlen);
}
ssize_t recvmsg(int s, struct msghdr *message, int flags)
{
CHECK_NULL_PTR(message);
if (message->msg_iovlen) {
CHECK_NULL_PTR(message->msg_iov);
}
return lwip_recvmsg(s, message, flags);
}
ssize_t send(int s, const void *dataptr, size_t size, int flags)
{
CHECK_NULL_PTR(dataptr);
return lwip_send(s, dataptr, size, flags);
}
ssize_t sendmsg(int s, const struct msghdr *message, int flags)
{
return lwip_sendmsg(s, message, flags);
}
ssize_t sendto(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen)
{
CHECK_NULL_PTR(dataptr);
if (to && tolen < sizeof(*to)) {
set_errno(EINVAL);
return -1;
}
return lwip_sendto(s, dataptr, size, flags, to, tolen);
}
int socket(int domain, int type, int protocol)
{
return lwip_socket(domain, type, protocol);
}
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{
return lwip_inet_ntop(af, src, dst, size);
}
int inet_pton(int af, const char *src, void *dst)
{
return lwip_inet_pton(af, src, dst);
}
int ioctlsocket(int s, long cmd, void *argp)
{
return lwip_ioctl(s, cmd, argp);
}
#if LWIP_SOCKET_SELECT
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout)
{
return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
}
#endif
#if LWIP_SOCKET_POLL
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
return lwip_poll(fds, nfds, timeout);
}
#endif
unsigned int if_nametoindex(const char *ifname)
{
return lwip_if_nametoindex(ifname);
}
#endif
#endif /* !LWIP_COMPAT_SOCKETS */
@@ -0,0 +1,344 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#include <lwip/debug.h>
#include <los_task.h>
#include <los_tick.h>
#include <los_queue.h>
#include <los_sem.h>
#include <los_mux.h>
#include "cmsis_os2.h"
#include <los_tick.h>
#include <los_config.h>
#ifndef LOSCFG_KERNEL_SMP
#define LOSCFG_KERNEL_SMP 0
#endif
#if (LOSCFG_KERNEL_SMP)
SPIN_LOCK_INIT(arch_protect_spin);
static u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
static int lwprot_count = 0;
#endif /* LOSCFG_KERNEL_SMP */
#define ROUND_UP_DIV(val, div) (((val) + (div) - 1) / (div))
#define LWIP_LOG_BUF_SIZE 64
/**
* Thread and System misc
*/
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio)
{
UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID;
UINT32 ret;
TSK_INIT_PARAM_S task = {0};
/* Create host Task */
task.pfnTaskEntry = (TSK_ENTRY_FUNC)thread;
task.uwStackSize = stackSize;
task.pcName = (char *)name;
task.usTaskPrio = prio;
task.uwArg = (UINTPTR)arg;
task.uwResved = LOS_TASK_STATUS_DETACHED;
ret = LOS_TaskCreate(&taskID, &task);
if (ret != LOS_OK) {
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret));
return -1;
}
return taskID;
}
void sys_init(void)
{
/* set rand seed to make random sequence diff on every startup */
UINT32 seedlsb = (UINT32)LOS_SysCycleGet();
srand(seedlsb);
}
u32_t sys_now(void)
{
/* Lwip docs mentioned like wraparound is not a problem in this funtion */
return (u32_t)osKernelGetTickCount();
}
/**
* Protector
*/
sys_prot_t sys_arch_protect(void)
{
#if (LOSCFG_KERNEL_SMP)
/* Note that we are using spinlock instead of mutex for LiteOS-SMP here:
* 1. spinlock is more effective for short critical region protection.
* 2. this function is called only in task context, not in interrupt handler.
* so it's not needed to disable interrupt.
*/
if (lwprot_thread != LOS_CurTaskIDGet()) {
/* We are locking the spinlock where it has not been locked before
* or is being locked by another thread */
LOS_SpinLock(&arch_protect_spin);
lwprot_thread = LOS_CurTaskIDGet();
lwprot_count = 1;
} else {
/* It is already locked by THIS thread */
lwprot_count++;
}
#else
LOS_TaskLock();
#endif /* LOSCFG_KERNEL_SMP */
return 0; /* return value is unused */
}
void sys_arch_unprotect(sys_prot_t pval)
{
LWIP_UNUSED_ARG(pval);
#if (LOSCFG_KERNEL_SMP)
if (lwprot_thread == LOS_CurTaskIDGet()) {
lwprot_count--;
if (lwprot_count == 0) {
lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
LOS_SpinUnlock(&arch_protect_spin);
}
}
#else
LOS_TaskUnlock();
#endif /* LOSCFG_KERNEL_SMP */
}
/**
* MessageBox
*/
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
{
CHAR qName[] = "lwIP";
UINT32 ret = LOS_QueueCreate(qName, (UINT16)size, mbox, 0, sizeof(void *));
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_CB_UNAVAILABLE:
case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY:
return ERR_MEM;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueCreate error %u\n", __FUNCTION__, ret));
return ERR_ARG;
}
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
/* Caution: the second parameter is NOT &msg */
UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), LOS_WAIT_FOREVER);
if (ret != LOS_OK) {
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret));
}
}
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
/* Caution: the second parameter is NOT &msg */
UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), 0);
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_ISFULL:
return ERR_MEM;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret));
return ERR_ARG;
}
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
{
return ERR_ARG;
}
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
{
void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */
UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), tick ? (UINT32)tick : LOS_WAIT_FOREVER);
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_ISEMPTY:
case LOS_ERRNO_QUEUE_TIMEOUT:
return SYS_ARCH_TIMEOUT;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret));
return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
}
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */
UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), 0);
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_ISEMPTY:
return SYS_MBOX_EMPTY;
case LOS_ERRNO_QUEUE_TIMEOUT:
return SYS_ARCH_TIMEOUT;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret));
return SYS_MBOX_EMPTY; /* Errors should be treated as timeout */
}
void sys_mbox_free(sys_mbox_t *mbox)
{
(void)LOS_QueueDelete(*mbox);
}
int sys_mbox_valid(sys_mbox_t *mbox)
{
QUEUE_INFO_S queueInfo;
return LOS_OK == LOS_QueueInfoGet(*mbox, &queueInfo);
}
void sys_mbox_set_invalid(sys_mbox_t *mbox)
{
*mbox = LOSCFG_BASE_IPC_QUEUE_LIMIT;
}
/**
* Semaphore
*/
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
{
UINT32 ret = LOS_SemCreate(count, sem);
if (ret != LOS_OK) {
return ERR_ARG;
}
return ERR_OK;
}
void sys_sem_signal(sys_sem_t *sem)
{
(void)LOS_SemPost(*sem);
}
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs)
{
UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
UINT32 ret = LOS_SemPend(*sem, tick ? (UINT32)tick : LOS_WAIT_FOREVER); // timeoutMs 0 means wait forever
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_SEM_TIMEOUT:
return SYS_ARCH_TIMEOUT;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_SemPend error %u\n", __FUNCTION__, ret));
return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
}
void sys_sem_free(sys_sem_t *sem)
{
(void)LOS_SemDelete(*sem);
}
int sys_sem_valid(sys_sem_t *sem)
{
return *sem != LOSCFG_BASE_IPC_SEM_LIMIT;
}
void sys_sem_set_invalid(sys_sem_t *sem)
{
*sem = LOSCFG_BASE_IPC_SEM_LIMIT;
}
/**
* Mutex
*/
err_t sys_mutex_new(sys_mutex_t *mutex)
{
UINT32 ret = LOS_MuxCreate(mutex);
if (ret != LOS_OK) {
return ERR_ARG;
}
return ERR_OK;
}
void sys_mutex_lock(sys_mutex_t *mutex)
{
(void)LOS_MuxPend(*mutex, LOS_WAIT_FOREVER);
}
void sys_mutex_unlock(sys_mutex_t *mutex)
{
(void)LOS_MuxPost(*mutex);
}
void sys_mutex_free(sys_mutex_t *mutex)
{
(void)LOS_MuxDelete(*mutex);
}
int sys_mutex_valid(sys_mutex_t *mutex)
{
return *mutex != LOSCFG_BASE_IPC_MUX_LIMIT;
}
void sys_mutex_set_invalid(sys_mutex_t *mutex)
{
*mutex = LOSCFG_BASE_IPC_MUX_LIMIT;
}
void HilogPrintf(const char *fmt, ...)
{
if ((fmt == NULL) || (strlen(fmt) == 0)) {
return;
}
int len;
char buf[LWIP_LOG_BUF_SIZE] = {0};
va_list ap;
va_start(ap, fmt);
len = vsprintf_s(buf, sizeof(buf) - 1, fmt, ap);
va_end(ap);
if (len < 0) {
HILOG_INFO(HILOG_MODULE_APP, "log param invalid or buf is not enough.");
return;
}
HILOG_INFO(HILOG_MODULE_APP, buf);
}
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef LWIP_TEST_H
#define LWIP_TEST_H
#include "lwip/arch.h"
#include "lwip/sockets.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include "securec.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int g_testCase;
extern int g_testError;
extern int g_testTemp;
#define LWIP_TEST_RET_OK 0
#define LWIP_TEST_RET_ERR 1
#define LOCALHOST "127.0.0.1"
#define STACK_IP LOCALHOST
#define STACK_PORT 2277
#define PEER_PORT STACK_PORT
#define SERVER_PORT STACK_PORT
#define CLIENT_PORT 2288
#define PEER_IP LOCALHOST
#define BUF_SIZE (128 * 1)
#define IOV_LENGTH 2
#define STACK_TEST_SIZE (0x800UL)
#define ICUNIT_ASSERT_NOT_EQUAL(a, b, c) if ((a) == (b)) { \
g_testError = (c); \
LWIP_ASSERT("lwip test", 0); \
}
#define ICUNIT_ASSERT_EQUAL(a, b, c) if ((a) != (b)) { \
g_testError = (c); \
LWIP_ASSERT("lwip test", 0); \
}
#define LogPrintln(fmt, ...) \
HILOG_INFO(HILOG_MODULE_APP, fmt "%c", \
##__VA_ARGS__, \
('\n' == " "fmt[sizeof(" "fmt)-2]) ? '\0' : '\n') // trailing newline is auto appended
#ifdef __cplusplus
}
#endif
#endif /* LWIP_TEST_H */
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#define TEST_CASE 110
int SocketTest(void)
{
LogPrintln("net_socket_test_001.c enter");
g_testCase = TEST_CASE;
int fd = socket(0, 0, 0);
LWIP_ASSERT("socket invalid param.", fd == -1);
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define MSG "Hi, I am UDP"
#define TEST_CASE 120
static char g_buf[BUF_SIZE + 1] = { 0 };
void UdpTestTask(void *p)
{
(void)p;
LogPrintln("net_socket_test_002.c enter");
g_testCase = TEST_CASE;
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
struct msghdr msg = { 0 };
struct iovec iov[IOV_LENGTH] = { 0 };
int recvCount = 0;
/* socket creation */
sfd = socket(AF_INET, SOCK_DGRAM, 0);
LWIP_ASSERT("socket invalid param.", sfd != -1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LWIP_ASSERT("socket invalid param.", ret == 0);
/* send */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), MSG);
ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr,
(socklen_t)sizeof(clnAddr));
LWIP_ASSERT("socket invalid param.", ret != -1);
ret = ioctlsocket(sfd, FIONREAD, &recvCount);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
LogPrintln("udp recv count %d", recvCount);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
&clnAddrLen);
LWIP_ASSERT("socket invalid param.", ret == strlen(MSG));
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), MSG);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = IOV_LENGTH;
iov[0].iov_base = g_buf;
iov[0].iov_len = strlen(MSG);
iov[1].iov_base = g_buf;
iov[1].iov_len = strlen(MSG);
ret = sendmsg(sfd, &msg, 0);
LWIP_ASSERT("socket invalid param.", ret == IOV_LENGTH * strlen(MSG));
/* recvmsg */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = g_buf;
iov[0].iov_len = sizeof(g_buf);
ret = recvmsg(sfd, &msg, 0);
LWIP_ASSERT("socket invalid param.", ret == IOV_LENGTH * strlen(MSG));
/* close socket */
ret = closesocket(sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
return;
}
int UdpTest()
{
int ret = sys_thread_new("udp_test", UdpTestTask, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return ret;
}
@@ -0,0 +1,251 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 130
static char g_buf[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
struct msghdr msg = { 0 };
struct iovec iov[IOV_LENGTH] = { 0 };
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG);
ret = send(sfd, g_buf, strlen(SRV_MSG), 0);
LogPrintln("server send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 5);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("server recv on socket %d: %d", sfd, ret);
LogPrintln("ser:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 6);
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = IOV_LENGTH;
iov[0].iov_base = g_buf;
iov[0].iov_len = strlen(SRV_MSG);
iov[1].iov_base = g_buf;
iov[1].iov_len = strlen(SRV_MSG);
ret = sendmsg(sfd, &msg, 0);
LogPrintln("sendmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(SRV_MSG), 7);
/* recvmsg */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = g_buf;
iov[0].iov_len = sizeof(g_buf);
ret = recvmsg(sfd, &msg, 0);
LogPrintln("recvmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(CLI_MSG), 8);
ret = shutdown(sfd, SHUT_RDWR);
LogPrintln("shutdown socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 9);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 11);
return 0;
}
static int SampleTcpClient()
{
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
int ret;
struct msghdr msg = { 0 };
struct iovec iov[IOV_LENGTH] = { 0 };
struct sockaddr addr;
socklen_t addrLen = sizeof(addr);
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(PEER_PORT);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* test getpeername */
ret = getpeername(sfd, &addr, &addrLen);
LogPrintln("getpeername %d %s:%d: %d", \
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 12);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 13);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(PEER_IP), 14);
/* test getsockname */
ret = getsockname(sfd, &addr, &addrLen);
LogPrintln("getsockname %d %s:%d: %d", \
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 15);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 16);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(STACK_IP), 17);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG);
ret = send(sfd, g_buf, strlen(CLI_MSG), 0);
LogPrintln("client send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 18);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("client recv on socket %d: %d", sfd, ret);
LogPrintln("cli:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 19);
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = IOV_LENGTH;
iov[0].iov_base = g_buf;
iov[0].iov_len = strlen(CLI_MSG);
iov[1].iov_base = g_buf;
iov[1].iov_len = strlen(CLI_MSG);
ret = sendmsg(sfd, &msg, 0);
LogPrintln("sendmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(CLI_MSG), 20);
/* recvmsg */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = g_buf;
iov[0].iov_len = sizeof(g_buf);
ret = recvmsg(sfd, &msg, 0);
LogPrintln("recvmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(SRV_MSG), 21);
ret = shutdown(sfd, SHUT_RDWR);
LogPrintln("shutdown socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 22);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTest()
{
LogPrintln("net_socket_test_003.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#define TEST_CASE 140
#define OPT_TIMEOUT 1000
int SockOptTest()
{
LogPrintln("net_socket_test_004.c enter");
g_testCase = TEST_CASE;
int ret, error, flag;
struct timeval timeout;
socklen_t len;
int fd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(fd, -1, 1);
error = -1;
len = sizeof(error);
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", \
fd, ret, error, len, errno);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ICUNIT_ASSERT_EQUAL(error, 0, 3);
len = sizeof(timeout);
ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, 4);
timeout.tv_sec = OPT_TIMEOUT;
len = sizeof(timeout);
ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, len);
ICUNIT_ASSERT_EQUAL(ret, 0, 5);
(void)memset_s(&timeout, len, 0, len);
ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, 6);
ICUNIT_ASSERT_EQUAL(timeout.tv_sec, OPT_TIMEOUT, 7);
error = -1;
len = sizeof(error);
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", \
fd, ret, error, len, errno);
ICUNIT_ASSERT_EQUAL(ret, 0, 8);
ICUNIT_ASSERT_EQUAL(error, 0, 9);
flag = 1;
ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
LogPrintln("setsockopt(TCP_NODELAY) ret=%d", ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 10);
ret = closesocket(fd);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#define TEST_CASE 150
int ByteOrderTest(void)
{
LogPrintln("net_socket_test_005.c enter");
#if BYTE_ORDER == LITTLE_ENDIAN
g_testCase = TEST_CASE + 1;
uint32_t hl = ntohl(0x12345678);
ICUNIT_ASSERT_EQUAL(hl, 0x78563412, 1);
uint32_t nl = htonl(0x12345678);
ICUNIT_ASSERT_EQUAL(nl, 0x78563412, 2);
uint16_t hs = ntohs(0x1234);
ICUNIT_ASSERT_EQUAL(hs, 0x3412, 3);
uint16_t ns = htons(0x1234);
ICUNIT_ASSERT_EQUAL(ns, 0x3412, 4);
#else
g_testCase = TEST_CASE;
uint32_t hl = ntohl(0x12345678);
ICUNIT_ASSERT_EQUAL(hl, 0x12345678, 5);
uint32_t nl = htonl(0x12345678);
ICUNIT_ASSERT_EQUAL(nl, 0x12345678, 6);
uint16_t hs = ntohs(0x1234);
ICUNIT_ASSERT_EQUAL(hs, 0x1234, 7);
uint16_t ns = htons(0x1234);
ICUNIT_ASSERT_EQUAL(ns, 0x1234, 8);
#endif
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#define TEST_CASE 160
#define TEMP_BUF_SIZE 32
int InetTest()
{
LogPrintln("net_socket_test_006.c enter");
g_testCase = TEST_CASE;
struct in_addr in;
int ret = inet_pton(AF_INET, "300.10.10.10", &in);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
ret = inet_pton(AF_INET, "10.11.12.13", &in);
ICUNIT_ASSERT_EQUAL(ret, 1, 2);
#if BYTE_ORDER == LITTLE_ENDIAN
g_testCase++;
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0d0c0b0a, 3);
#else
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0a0b0c0d, 4);
#endif
const char *p = inet_ntoa(in);
ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, 5);
char buf[TEMP_BUF_SIZE];
p = inet_ntop(AF_INET, &in, buf, sizeof(buf));
ICUNIT_ASSERT_EQUAL(p, buf, 6);
ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, 7);
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
static char g_buf[BUF_SIZE + 1] = { 0 };
static char g_buf_temp[BUF_SIZE + 1] = { 0 };
#define SEND_UDP_COUNT 10000 // send count
#define TEST_CASE 170
static void UdpTestMoreTask(void *p)
{
(void)p;
LogPrintln("net_socket_test_007.c enter");
if (g_testCase < TEST_CASE) {
g_testCase = TEST_CASE;
} else {
g_testCase++;
}
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
int i;
/* socket creation */
sfd = socket(AF_INET, SOCK_DGRAM, 0);
LWIP_ASSERT("socket invalid param.", sfd != -1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LWIP_ASSERT("socket invalid param.", ret == 0);
/* send */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
if (g_buf_temp[0] == '\0') {
for (i = 0; i < BUF_SIZE; i++) {
g_buf_temp[i] = 'U';
}
g_buf_temp[BUF_SIZE] = '\0';
}
LogPrintln("udp begin send");
for (i = 0; i < SEND_UDP_COUNT; i++) {
ret = memcpy_s(g_buf, sizeof(g_buf), g_buf_temp, sizeof(g_buf_temp));
ICUNIT_ASSERT_EQUAL(ret, EOK, 1);
ret = sendto(sfd, g_buf, BUF_SIZE, 0, (struct sockaddr*)&clnAddr, (socklen_t)sizeof(clnAddr));
LWIP_ASSERT("socket invalid param.", ret != -1);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
&clnAddrLen);
LWIP_ASSERT("socket invalid param.", ret == BUF_SIZE);
}
LogPrintln("udp end send");
/* close socket */
ret = closesocket(sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
}
void UdpTestMore()
{
int ret;
ret = sys_thread_new("udp_more", UdpTestMoreTask, NULL,
STACK_TEST_SIZE * 2, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10);
}
@@ -0,0 +1,185 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SEND_TCP_COUNT 1000 // send count
#define STACK_PORT_8 2288
#define TEST_CASE 180
static char g_serverSendBuf[BUF_SIZE + 1] = { 0 };
static char g_clientRecvBuf[BUF_SIZE + 1] = { 0 };
static void InitMsgBuf()
{
int i;
if (g_serverSendBuf[0] != '\0') {
return;
}
for (i = 0; i < BUF_SIZE; i++) {
g_serverSendBuf[i] = 'S';
}
g_serverSendBuf[BUF_SIZE] = '\0';
}
static int SampleTcpServer()
{
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
int i;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_8);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
for (i = 0; i < SEND_TCP_COUNT; i++) {
/* send */
ret = send(sfd, g_serverSendBuf, BUF_SIZE, 0);
ICUNIT_ASSERT_EQUAL(ret, BUF_SIZE, 5);
}
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 7);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
return 0;
}
static int SampleTcpClient()
{
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
int i;
struct sockaddr addr;
socklen_t addrLen = sizeof(addr);
int recvCount = 0;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 7);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_8);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 8);
/* test getpeername */
ret = getpeername(sfd, &addr, &addrLen);
LogPrintln("getpeername %d %s:%d: %d",
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 9);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 10);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(PEER_IP), 11);
/* test getsockname */
ret = getsockname(sfd, &addr, &addrLen);
LogPrintln("getsockname %d %s:%d: %d",
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 12);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 13);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(STACK_IP), 14);
LogPrintln("tcp begin recv");
for (i = 0; i < 2 * SEND_TCP_COUNT; i++) {
/* recv */
(void)memset_s(g_clientRecvBuf, sizeof(g_clientRecvBuf), 0, sizeof(g_clientRecvBuf));
ret = recv(sfd, g_clientRecvBuf, BUF_SIZE, 0);
recvCount += ret;
if (recvCount >= BUF_SIZE * SEND_TCP_COUNT) {
LogPrintln("client recv on socket %d: %d, i = %d", sfd, recvCount, i);
break;
}
}
ICUNIT_ASSERT_EQUAL(recvCount, BUF_SIZE * SEND_TCP_COUNT, recvCount);
LogPrintln("tcp end recv");
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 17);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTestMore()
{
LogPrintln("net_socket_test_008.c enter");
if (g_testCase < TEST_CASE) {
g_testCase = TEST_CASE;
}
int ret;
InitMsgBuf();
ret = sys_thread_new("tcp_server_more", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 17);
ret = sys_thread_new("tcp_client_more", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 18);
}
@@ -0,0 +1,165 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 190
#define STACK_PORT_9 2299
#define TIME_OUT 10 // timeout 10s
static char g_buf[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
#if LWIP_SOCKET_SELECT
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
fd_set fdsr;
struct timeval tv;
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_9);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
FD_ZERO(&fdsr);
FD_SET(lsfd, &fdsr);
// timeout setting
tv.tv_sec = TIME_OUT;
tv.tv_usec = 0;
ret = select(lsfd + 1, &fdsr, NULL, NULL, &tv);
if (ret < 0) {
LogPrintln("select error");
ICUNIT_ASSERT_EQUAL(-1, 0, 4);
} else if (ret == 0) {
LogPrintln("select timeout");
ICUNIT_ASSERT_EQUAL(-1, 0, 5);
}
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 6);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG);
ret = send(sfd, g_buf, strlen(SRV_MSG), 0);
LogPrintln("server send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 7);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 9);
#endif
return 0;
}
static int SampleTcpClient()
{
#if LWIP_SOCKET_SELECT
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_9);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("client recv on socket %d: %d", sfd, ret);
LogPrintln("cli:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 12);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13);
#endif
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTestSelect()
{
LogPrintln("net_socket_test_009.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_select", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_select", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,160 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 200
#define STACK_PORT_10 2230
#define POLL_OPEN_MAX 10
#define TIME_OUT (1000 * 10) // timeout 10s
static char g_buf[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
#if LWIP_SOCKET_POLL
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
struct pollfd client[POLL_OPEN_MAX] = {0};
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_10);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
client[0].fd = lsfd;
client[0].events = POLLIN;
ret = poll(client, 1, TIME_OUT);
if (ret < 0) {
LogPrintln("poll error");
ICUNIT_ASSERT_EQUAL(-1, 0, 4);
} else if (ret == 0) {
LogPrintln("poll timeout");
ICUNIT_ASSERT_EQUAL(-1, 0, 5);
}
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 6);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("server recv on socket %d: %d", sfd, ret);
LogPrintln("ser:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 7);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 9);
#endif
return 0;
}
static int SampleTcpClient()
{
#if LWIP_SOCKET_POLL
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_10);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG);
ret = send(sfd, g_buf, strlen(CLI_MSG), 0);
LogPrintln("client send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 12);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13);
#endif
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTestPoll()
{
LogPrintln("net_socket_test_010.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_poll", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_poll", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,449 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include <lwip/netif.h>
#include <lwip/netifapi.h>
#include <lwip/pbuf.h>
#include <lwip/ip4_addr.h>
#include <lwip/ip4.h>
#include <lwip/ip.h>
#include <lwip/def.h>
#include <lwip/udp.h>
#include <lwip/inet_chksum.h>
#include "lwip/prot/iana.h"
#define MSG "Hi, I am testing BT netif."
#define STACK_IP_BT "192.168.167.1"
#define PEER_IP_BT "100.100.100.100"
#define GATEWAY_IP_BT "192.168.167.239"
#define NETIF_MAC "121212"
#define PEER_MAC "454545"
#define NETIF_NAME_BT "bt1000"
#define TEST_CASE 210
static char g_buf[BUF_SIZE + 1] = { 0 };
struct netif *btProxyNf = NULL;
static void ReplayArpTask();
static void ArpPackageProc(struct netif *netif, struct pbuf *p);
extern void driverif_input(struct netif *netif, struct pbuf *p);
static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p);
static void ReplayUdpEncodeEthernet(struct netif *netif, struct pbuf *p)
{
int ret;
ret = pbuf_add_header(p, SIZEOF_ETH_HDR);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
struct eth_hdr *ethhdr;
ethhdr = (struct eth_hdr *)p->payload;
ethhdr->type = lwip_htons(ETHTYPE_IP);
SMEMCPY(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
SMEMCPY(&ethhdr->src, PEER_MAC, ETH_HWADDR_LEN);
driverif_input(netif, p);
}
static void ReplayUdpEncodeIp(struct pbuf *p, ip4_addr_t *src, ip4_addr_t *dest)
{
struct ip_hdr *iphdr;
int ret;
#if CHECKSUM_GEN_IP_INLINE
u32_t chk_sum = 0;
#endif /* CHECKSUM_GEN_IP_INLINE */
// ip header
ret = pbuf_add_header(p, IP_HLEN);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
iphdr = (struct ip_hdr *)p->payload;
IPH_TTL_SET(iphdr, UDP_TTL);
IPH_PROTO_SET(iphdr, IP_PROTO_UDP);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += PP_NTOHS(IP_PROTO_UDP | (ttl << 8));
#endif /* CHECKSUM_GEN_IP_INLINE */
/* dest cannot be NULL here */
ip4_addr_copy(iphdr->dest, *dest);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
#endif /* CHECKSUM_GEN_IP_INLINE */
u16_t ip_hlen = IP_HLEN;
IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
IPH_TOS_SET(iphdr, 0);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
#endif /* CHECKSUM_GEN_IP_INLINE */
IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
#if CHECKSUM_GEN_IP_INLINE
chk_sum += iphdr->_len;
#endif /* CHECKSUM_GEN_IP_INLINE */
IPH_OFFSET_SET(iphdr, 0);
IPH_ID_SET(iphdr, lwip_htons(0));
#if CHECKSUM_GEN_IP_INLINE
chk_sum += iphdr->_id;
#endif /* CHECKSUM_GEN_IP_INLINE */
ip4_addr_copy(iphdr->src, *src);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = (chk_sum >> 16) + chk_sum;
chk_sum = ~chk_sum;
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
iphdr->_chksum = (u16_t)chk_sum; /* network order */
}
#if LWIP_CHECKSUM_CTRL_PER_NETIF
else {
IPH_CHKSUM_SET(iphdr, 0);
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#else /* CHECKSUM_GEN_IP_INLINE */
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 */
#endif /* CHECKSUM_GEN_IP_INLINE */
ReplayUdpEncodeEthernet(btProxyNf, p);
}
static void ReplayUdp(void *ptemp)
{
struct udp_hdr *udphdr;
ip4_addr_t sipaddr, dipaddr;
int size = strlen(MSG);
int ret;
(void)ptemp;
LogPrintln("encode udp replay packet");
inet_pton(AF_INET, PEER_IP_BT, &sipaddr);
inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
u16_t chksum = LWIP_CHKSUM_COPY(p->payload, MSG, size);
// udp header
ret = pbuf_add_header(p, UDP_HLEN);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
udphdr = (struct udp_hdr *)p->payload;
udphdr->src = lwip_htons(STACK_PORT);
udphdr->dest = lwip_htons(STACK_PORT);
udphdr->len = lwip_htons(p->tot_len);
/* in UDP, 0 checksum means 'no checksum' */
u16_t udpchksum = ip_chksum_pseudo_partial(p, IP_PROTO_UDP, p->tot_len, UDP_HLEN, &sipaddr, &dipaddr);
u32_t acc = udpchksum + (u16_t)~(chksum);
udpchksum = FOLD_U32T(acc);
if (udpchksum == 0x0000) {
udpchksum = 0xffff;
}
udphdr->chksum = udpchksum;
udphdr->chksum = 0;
ReplayUdpEncodeIp(p, &sipaddr, &dipaddr);
}
static void ReplayUdpTask()
{
int ret;
ret = sys_thread_new("replay_udp", ReplayUdp, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 3);
}
static void ParsePackageIpUdp(struct netif *netif, struct pbuf *btBuf)
{
// get scr_addr and dest_addr from ip head
const struct ip_hdr *iphdr;
iphdr = (const struct ip_hdr *)btBuf->payload;
ip4_addr_p_t ip4_addr_scr = iphdr->src;
ip4_addr_p_t ip4_addr_dest = iphdr->dest;
char buf[32];
int dataLen;
// get scr_port and dest port from tcp head
u16_t scr_port, dest_port;
void *data;
struct udp_hdr *udphdr;
udphdr = (struct udp_hdr *)((u8_t *)iphdr + IPH_HL_BYTES(iphdr));
scr_port = udphdr->src;
dest_port = udphdr->dest;
data = (void *)((u8_t *)udphdr + UDP_HLEN);
LogPrintln("======Bt netif send package======");
LogPrintln("netif full name %s", netif->full_name);
(void)inet_ntop(AF_INET, &ip4_addr_scr.addr, buf, sizeof(buf));
LogPrintln("package src ip %s", buf);
(void)inet_ntop(AF_INET, &ip4_addr_dest.addr, buf, sizeof(buf));
LogPrintln("package dest ip %s", buf);
LogPrintln("package src port %d", lwip_ntohs(scr_port));
LogPrintln("package dest port %d", lwip_ntohs(dest_port));
LogPrintln("send data %s", (char *)data);
dataLen = lwip_ntohs(udphdr->len) - UDP_HLEN;
LogPrintln("send data length %d", dataLen);
ICUNIT_ASSERT_EQUAL(dataLen, strlen(MSG), 4);
LogPrintln("=================================");
// 回应udp报文
ReplayUdpTask();
}
static void ParsePackageEthernet(struct netif *netif, struct pbuf *p)
{
u16_t next_hdr_offset = SIZEOF_ETH_HDR;
// get src mac and dest mac
struct eth_hdr *ethhdr;
ethhdr = (struct eth_hdr *)p->payload;
u16_t type = ethhdr->type;
LogPrintln("ParsePackageEthernet type is %d", type);
switch (type) {
#if LWIP_IPV4 && LWIP_ARP
/* IP packet? */
case PP_HTONS(ETHTYPE_IP): // 0x0008
if (!(netif->flags & NETIF_FLAG_ETHARP)) {
return;
}
/* skip Ethernet header (min. size checked above) */
if (pbuf_remove_header(p, next_hdr_offset)) {
return;
} else {
/* pass to IP layer */
ParsePackageIpUdp(netif, p);
}
break;
case PP_HTONS(ETHTYPE_ARP): // 0x0608
if (!(netif->flags & NETIF_FLAG_ETHARP)) {
return;
}
/* skip Ethernet header (min. size checked above) */
if (pbuf_remove_header(p, next_hdr_offset)) {
return;
} else {
/* pass p to ARP module */
LogPrintln("recv arp packet");
ArpPackageProc(netif, p);
}
break;
#endif /* LWIP_IPV4 && LWIP_ARP */
default:
LogPrintln("type is other %d", type);
break;
}
}
static void BtProxySend(struct netif *netif, struct pbuf *p)
{
if (netif == NULL || p == NULL) {
LogPrintln("%s : netif = NUll or p = NULL!", __func__);
return;
}
#if ETH_PAD_SIZE
(void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
ParsePackageEthernet(netif, p);
}
static struct netif *CreateBtNetIf()
{
struct netif *btNetif = NULL;
btNetif = (struct netif *)malloc(sizeof(struct netif));
if (btNetif == NULL) {
LogPrintln("%s fail : netif malloc fail!", __func__);
LWIP_ASSERT("btNetif malloc fail.", 0);
return NULL;
}
(void)memset_s(btNetif, sizeof(struct netif), 0, sizeof(struct netif));
btNetif->drv_send = BtProxySend;
btNetif->link_layer_type = BT_PROXY_IF;
btNetif->hwaddr_len = ETH_HWADDR_LEN;
(void)memcpy_s(&btNetif->hwaddr, sizeof(btNetif->hwaddr), NETIF_MAC, ETH_HWADDR_LEN);
(void)memcpy_s(&btNetif->full_name, sizeof(btNetif->full_name), NETIF_NAME_BT, sizeof(NETIF_NAME_BT));
ip4_addr_t gw, ipaddr, netmask;
IP4_ADDR(&gw, 192, 168, 167, 239);
IP4_ADDR(&ipaddr, 192, 168, 167, 1);
IP4_ADDR(&netmask, 255, 255, 255, 255);
int ret = 0;
if ((ret = netifapi_netif_add(btNetif, &ipaddr, &netmask, &gw, btNetif, driverif_init, tcpip_input)) != ERR_OK) {
LogPrintln("%s : netifapi_netif_add fail!,ret=%d", __func__, ret);
LWIP_ASSERT("btNetif add fail.", 0);
return NULL;
}
LogPrintln("netifapi_netif_add success!");
netif_set_link_up(btNetif);
netifapi_netif_set_up(btNetif);
return btNetif;
}
static void UdpTestNetifTask(void *p)
{
(void)p;
LogPrintln("net_socket_test_011.c enter");
g_testCase = TEST_CASE;
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
struct ifreq nif;
int ret;
// 注册网卡
btProxyNf = CreateBtNetIf();
/* socket creation */
sfd = socket(AF_INET, SOCK_DGRAM, 0);
LWIP_ASSERT("socket invalid param.", sfd != -1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP_BT);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LWIP_ASSERT("socket invalid param.", ret == 0);
/* 指定网卡接口 */
char *inface = NETIF_NAME_BT;
(void)strcpy_s(nif.ifr_name, sizeof(nif.ifr_name), inface);
if (setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&nif, sizeof(nif)) < 0) {
LogPrintln("set intaface fail");
LWIP_ASSERT("set intaface fail.", 0);
}
/* send */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP_BT);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), MSG);
ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr,
(socklen_t)sizeof(clnAddr));
LogPrintln("client send success: %d", sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
&clnAddrLen);
LWIP_ASSERT("socket invalid param.", ret == strlen(MSG));
LogPrintln("cli recv: %s", g_buf);
/* close socket */
ret = closesocket(sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
return;
}
int UdpTestNetif()
{
int ret = sys_thread_new("udp_test_netif", UdpTestNetifTask, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return ret;
}
static void ArpPackageProc(struct netif *netif, struct pbuf *p)
{
struct etharp_hdr *hdr;
ip4_addr_t sipaddr, dipaddr;
hdr = (struct etharp_hdr *)p->payload;
if (hdr->opcode != PP_HTONS(ARP_REQUEST)) {
LogPrintln("opcode %d is not arp request", hdr->opcode);
return;
}
inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr);
inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
if (memcmp(&hdr->dipaddr, &sipaddr, sizeof(ip4_addr_t)) != EOK) {
LogPrintln("hdr->dipaddr %u is invalid", hdr->dipaddr);
return;
}
// 回应arp报文
ReplayArpTask();
}
static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p)
{
int ret;
ret = pbuf_add_header(p, SIZEOF_ETH_HDR);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
struct eth_hdr *ethhdr;
ethhdr = (struct eth_hdr *)p->payload;
ethhdr->type = lwip_htons(ETHTYPE_ARP);
SMEMCPY(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
SMEMCPY(&ethhdr->src, PEER_MAC, ETH_HWADDR_LEN);
driverif_input(netif, p);
}
static void ReplayArp(void *ptemp)
{
struct etharp_hdr *hdr;
ip4_addr_t sipaddr, dipaddr;
(void)ptemp;
LogPrintln("encode arp replay packet");
inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr);
inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
struct pbuf *p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);
hdr = (struct etharp_hdr *)p->payload;
hdr->opcode = PP_HTONS(ARP_REPLY);
/* Write the ARP MAC-Addresses */
SMEMCPY(&hdr->shwaddr, PEER_MAC, ETH_HWADDR_LEN);
SMEMCPY(&hdr->dhwaddr, NETIF_MAC, ETH_HWADDR_LEN);
/* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
* structure packing. */
IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, &sipaddr);
IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, &dipaddr);
hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET);
hdr->proto = PP_HTONS(ETHTYPE_IP);
/* set hwlen and protolen */
hdr->hwlen = ETH_HWADDR_LEN;
hdr->protolen = sizeof(ip4_addr_t);
ReplayArpEncodeEthernet(btProxyNf, p);
}
static void ReplayArpTask()
{
int ret;
ret = sys_thread_new("replay_arp", ReplayArp, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
}
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 220
#define TEST_COUNT 100
#define STACK_PORT_TCP_DUP_START 3000
static int g_portServer = STACK_PORT_TCP_DUP_START;
static int g_portClient = STACK_PORT_TCP_DUP_START;
static char g_bufServer[BUF_SIZE + 1] = { 0 };
static char g_bufClient[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(g_portServer);
g_portServer++;
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
/* send */
(void)memset_s(g_bufServer, sizeof(g_bufServer), 0, sizeof(g_bufServer));
(void)strcpy_s(g_bufServer, sizeof(g_bufServer), SRV_MSG);
ret = send(sfd, g_bufServer, strlen(SRV_MSG), 0);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 5);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 11);
return 0;
}
static int SampleTcpClient()
{
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(g_portClient);
g_portClient++;
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* recv */
(void)memset_s(g_bufClient, sizeof(g_bufClient), 0, sizeof(g_bufClient));
ret = recv(sfd, g_bufClient, sizeof(g_bufClient), 0);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 19);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
g_testCase++;
int i;
for (i = 0; i < TEST_COUNT; i++) {
(void)SampleTcpServer();
}
LogPrintln("tcp server g_portServer = %d", g_portServer);
}
static void TcpClientRoutine(void *p)
{
(void)p;
g_testCase++;
int i;
for (i = 0; i < TEST_COUNT; i++) {
(void)SampleTcpClient();
}
LogPrintln("tcp server g_portClient = %d", g_portClient);
}
void TcpTestDup()
{
LogPrintln("net_socket_test_012.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_dup", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_dup", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define TEST_CASE 230
#define STACK_PORT_TCP_LONG 2231
#define TCP_LONG_BUF_SIZE (2 * 1024)
static int SampleTcpServer()
{
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
static char serverBuf[TCP_LONG_BUF_SIZE] = {0};
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_TCP_LONG);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
/* send */
ret = send(sfd, serverBuf, TCP_LONG_BUF_SIZE, 0);
ICUNIT_ASSERT_EQUAL(ret, TCP_LONG_BUF_SIZE, 6);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 7);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
return 0;
}
static int SampleTcpClient()
{
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret, i;
int recvCount = 0;
static char clientBuf[TCP_LONG_BUF_SIZE] = {0};
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 9);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_TCP_LONG);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 10);
/* recv */
for (i = 0; i < TCP_LONG_BUF_SIZE; i++) {
ret = recv(sfd, clientBuf, TCP_LONG_BUF_SIZE, 0);
recvCount += ret;
if (recvCount >= TCP_LONG_BUF_SIZE) {
LogPrintln("client recv on socket %d: %d, i = %d", sfd, recvCount, i);
break;
}
}
ICUNIT_ASSERT_NOT_EQUAL(i, TCP_LONG_BUF_SIZE, 12);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
g_testCase++;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
g_testCase++;
(void)SampleTcpClient();
}
void TcpTestLong()
{
LogPrintln("net_socket_test_013.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_long", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_long", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,145 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "sys/socket.h"
#include "hos_cmsis_adp.h"
#define LWIP_TEST_TIMEOUT 1000 // timeout 1s
#define LWIP_TEST_COUNT_FLAG 100
#define SOCKET_TEST 310
#define UDP_TEST 320
#define TCP_TEST 330
#define OPT_TEST 340
#define ORDER_TEST 350
#define INET_TEST 360
#define UDP_MORE_TEST 370
#define TCP_MORE_TEST 380
#define TCP_SELECT_TEST 390
#define TCP_POLL_TEST 400
#define NETIF_TEST 410
#define TCP_DUP_TEST 420
#define TCP_LONG_TEST 430
int g_lwipTimerCount = 0;
int g_testCase = LWIP_TEST_COUNT_FLAG;
int g_testError = 0;
int g_testTemp = LWIP_TEST_COUNT_FLAG;
extern void abort(void);
extern int SocketTest(void);
extern int UdpTest(void);
extern void TcpTest();
extern int SockOptTest();
extern int ByteOrderTest(void);
extern int InetTest();
extern int UdpTestMore(void);
extern void TcpTestMore();
extern void TcpTestSelect();
extern void TcpTestPoll();
extern int UdpTestNetif(void);
extern void TcpTestDup();
extern void TcpTestLong();
// time out 1s
static void LwipTestTimeoutCallback(void const *argument)
{
g_lwipTimerCount++;
switch (g_lwipTimerCount) {
case SOCKET_TEST:
SocketTest();
break;
case UDP_TEST:
UdpTest();
break;
case TCP_TEST:
TcpTest();
break;
case OPT_TEST:
SockOptTest();
break;
case ORDER_TEST:
ByteOrderTest();
break;
case INET_TEST:
InetTest();
break;
case UDP_MORE_TEST:
UdpTestMore();
break;
case TCP_MORE_TEST:
TcpTestMore();
break;
case TCP_SELECT_TEST:
TcpTestSelect();
break;
case TCP_POLL_TEST:
TcpTestPoll();
break;
case NETIF_TEST:
UdpTestNetif();
break;
case TCP_DUP_TEST:
TcpTestDup();
break;
case TCP_LONG_TEST:
TcpTestLong();
break;
default:
break;
}
}
osTimerId_t g_lwipTestTimerId = NULL;
void LwipTestStartTimer(uint32_t timeout)
{
osStatus_t status;
if (g_lwipTestTimerId != NULL) {
status = osTimerStart(g_lwipTestTimerId, timeout);
if (status != osOK) {
return;
}
} else {
g_lwipTestTimerId = osTimerNew((osTimerFunc_t)LwipTestTimeoutCallback, osTimerPeriodic, NULL, NULL);
if (g_lwipTestTimerId == NULL) {
return;
}
status = osTimerStart(g_lwipTestTimerId, timeout);
if (status != osOK) {
return;
}
}
}
void LwipTestEnter()
{
LwipTestStartTimer(LWIP_TEST_TIMEOUT);
}
@@ -0,0 +1,39 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
static_library("pm") {
sources = [ "los_pm.c" ]
include_dirs = [
"../../kernel/include",
"../../kernel/arch/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,663 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#include "los_pm.h"
#include "securec.h"
#include "los_sched.h"
#include "los_timer.h"
#include "los_memory.h"
#if (LOSCFG_KERNEL_PM == 1)
#define OS_PM_NODE_FREE 0x80000000U
#define OS_PM_LOCK_MAX 0xFFFFU
typedef UINT32 (*Suspend)(VOID);
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
typedef struct {
CHAR *name;
UINT32 count;
LOS_DL_LIST list;
} OsPmLockCB;
#endif
typedef struct {
LOS_SysSleepEnum pmMode;
LOS_SysSleepEnum sysMode;
UINT16 lock;
BOOL isWake;
LosPmDevice *device;
LosPmSysctrl *sysctrl;
LosPmTickTimer *tickTimer;
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
UINT64 enterSleepTime;
#endif
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
LOS_DL_LIST lockList;
#endif
} LosPmCB;
STATIC LosPmCB g_pmCB;
STATIC LosPmSysctrl *g_sysctrl = NULL;
STATIC UINT64 g_pmSleepTime;
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
STATIC VOID OsPmTickTimerStart(LosPmCB *pm)
{
UINT32 intSave;
UINT64 currTime, sleepTime, realSleepTime;
LosPmTickTimer *tickTimer = pm->tickTimer;
intSave = LOS_IntLock();
/* Restore the main CPU frequency */
sleepTime = tickTimer->timerCycleGet();
tickTimer->timerStop();
realSleepTime = OS_SYS_CYCLE_TO_NS(sleepTime, tickTimer->freq);
realSleepTime = OS_SYS_NS_TO_CYCLE(realSleepTime, OS_SYS_CLOCK);
currTime = pm->enterSleepTime + realSleepTime;
pm->enterSleepTime = 0;
OsSchedTimerBaseReset(currTime);
OsSchedUpdateExpireTime(currTime, FALSE);
tickTimer->tickUnlock();
LOS_IntRestore(intSave);
return;
}
STATIC VOID OsPmTickTimerStop(LosPmCB *pm)
{
UINT64 sleepCycle;
UINT64 realSleepTime = g_pmSleepTime;
LosPmTickTimer *tickTimer = pm->tickTimer;
if (realSleepTime == 0) {
return;
}
sleepCycle = OS_SYS_CYCLE_TO_NS(realSleepTime, OS_SYS_CLOCK);
sleepCycle = OS_SYS_NS_TO_CYCLE(sleepCycle, tickTimer->freq);
/* The main CPU reduces the frequency */
pm->enterSleepTime = OsGetCurrSchedTimeCycle();
tickTimer->tickLock();
tickTimer->timerStart(sleepCycle);
return;
}
#endif
STATIC VOID OsPmTickTimerResume(LosPmCB *pm)
{
if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->tickTimer->tickUnlock != NULL)) {
pm->tickTimer->tickUnlock();
} else {
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
/* Sys tick timer is restored from low power mode */
if (pm->enterSleepTime != 0) {
OsPmTickTimerStart(pm);
}
#endif
}
}
STATIC VOID OsPmCpuResume(LosPmCB *pm)
{
if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) && (pm->sysctrl->normalResume != NULL)) {
pm->sysctrl->normalResume();
} else if ((pm->sysMode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightResume != NULL)) {
pm->sysctrl->lightResume();
} else if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepResume != NULL)) {
pm->sysctrl->deepResume();
}
}
STATIC Suspend OsPmCpuSuspend(LosPmCB *pm)
{
Suspend sysSuspend = NULL;
/* cpu enter low power mode */
LOS_ASSERT(pm->sysctrl != NULL);
if (pm->sysMode == LOS_SYS_NORMAL_SLEEP) {
sysSuspend = pm->sysctrl->normalSuspend;
} else if (pm->sysMode == LOS_SYS_LIGHT_SLEEP) {
sysSuspend = pm->sysctrl->lightSuspend;
} else if (pm->sysMode == LOS_SYS_DEEP_SLEEP) {
sysSuspend = pm->sysctrl->deepSuspend;
} else {
sysSuspend = pm->sysctrl->shutdownSuspend;
}
LOS_ASSERT(sysSuspend != NULL);
return sysSuspend;
}
STATIC VOID OsPmTickTimerSuspend(LosPmCB *pm)
{
if (((pm->sysMode == LOS_SYS_DEEP_SLEEP) || (pm->sysMode == LOS_SYS_SHUTDOWN)) &&
(pm->tickTimer->tickLock != NULL)) {
pm->tickTimer->tickLock();
} else {
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
/* Sys tick timer enter low power mode */
if (pm->tickTimer == NULL) {
return;
}
if ((pm->tickTimer->timerStart != NULL) &&
(pm->tickTimer->timerStop != NULL) &&
(pm->tickTimer->timerCycleGet == NULL) &&
(pm->tickTimer->freq != 0)) {
OsPmTickTimerStop(pm);
}
#endif
}
}
STATIC VOID OsPmEnter(BOOL isIdle)
{
UINT32 ret;
UINT32 intSave;
Suspend sysSuspend = NULL;
LosPmCB *pm = &g_pmCB;
BOOL isTaskLock = FALSE;
intSave = LOS_IntLock();
pm->sysMode = pm->pmMode;
if (isIdle) {
if ((pm->sysMode != LOS_SYS_NORMAL_SLEEP) && (pm->sysMode != LOS_SYS_LIGHT_SLEEP)) {
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
}
} else {
if ((pm->sysMode != LOS_SYS_DEEP_SLEEP) && (pm->sysMode != LOS_SYS_SHUTDOWN)) {
LOS_IntRestore(intSave);
return;
}
}
if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) || (pm->sysMode == LOS_SYS_LIGHT_SLEEP)) {
if (pm->lock > 0) {
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
}
} else if (pm->lock > 0) {
LOS_IntRestore(intSave);
return;
}
if (pm->sysMode != LOS_SYS_NORMAL_SLEEP) {
pm->isWake = FALSE;
LOS_TaskLock();
isTaskLock = TRUE;
ret = pm->device->suspend((UINT32)pm->sysMode);
if (ret != LOS_OK) {
goto EXIT;
}
}
OsPmTickTimerSuspend(pm);
sysSuspend = OsPmCpuSuspend(pm);
LOS_IntRestore(intSave);
if (!isTaskLock || (isTaskLock && !pm->isWake)) {
(VOID)sysSuspend();
}
intSave = LOS_IntLock();
OsPmCpuResume(pm);
OsPmTickTimerResume(pm);
if (pm->sysMode != LOS_SYS_NORMAL_SLEEP) {
pm->device->resume((UINT32)pm->sysMode);
}
if (pm->pmMode == LOS_SYS_DEEP_SLEEP) {
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
}
EXIT:
LOS_IntRestore(intSave);
if (isTaskLock) {
LOS_TaskUnlock();
}
return;
}
STATIC VOID OsPmTask(VOID)
{
OsPmEnter(FALSE);
}
STATIC UINT32 OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device)
{
UINT32 intSave;
if ((device->suspend == NULL) || (device->resume == NULL)) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
intSave = LOS_IntLock();
pm->device = device;
LOS_IntRestore(intSave);
return LOS_OK;
}
STATIC UINT32 OsPmTickTimerRegister(LosPmCB *pm, LosPmTickTimer *tickTimer)
{
UINT32 intSave;
intSave = LOS_IntLock();
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
pm->enterSleepTime = 0;
#endif
pm->tickTimer = tickTimer;
LOS_IntRestore(intSave);
return LOS_OK;
}
STATIC UINT32 OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl)
{
UINT32 intSave;
if (sysctrl->normalSuspend == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
intSave = LOS_IntLock();
pm->sysctrl = sysctrl;
LOS_IntRestore(intSave);
return LOS_OK;
}
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node)
{
LosPmCB *pm = &g_pmCB;
if (node == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
switch (type) {
case LOS_PM_TYPE_DEVICE:
return OsPmDeviceRegister(pm, (LosPmDevice *)node);
case LOS_PM_TYPE_TICK_TIMER:
return OsPmTickTimerRegister(pm, (LosPmTickTimer *)node);
case LOS_PM_TYPE_SYSCTRL:
return OsPmSysctrlRegister(pm, (LosPmSysctrl *)node);
default:
break;
}
return LOS_ERRNO_PM_INVALID_TYPE;
}
STATIC UINT32 OsPmDeviceUnregister(LosPmCB *pm, LosPmDevice *device)
{
UINT32 intSave;
intSave = LOS_IntLock();
if (pm->device == device) {
pm->device = NULL;
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
LOS_IntRestore(intSave);
return LOS_OK;
}
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_INVALID_NODE;
}
STATIC UINT32 OsPmTickTimerUnregister(LosPmCB *pm, LosPmTickTimer *tickTimer)
{
UINT32 intSave;
intSave = LOS_IntLock();
if (pm->tickTimer == tickTimer) {
pm->tickTimer = NULL;
if ((pm->pmMode != LOS_SYS_NORMAL_SLEEP) && (pm->pmMode != LOS_SYS_LIGHT_SLEEP)) {
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
}
LOS_IntRestore(intSave);
return LOS_OK;
}
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_INVALID_NODE;
}
STATIC UINT32 OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl)
{
UINT32 intSave;
VOID *freeNode = NULL;
intSave = LOS_IntLock();
if (pm->sysctrl == sysctrl) {
if (pm->sysctrl == g_sysctrl) {
freeNode = (VOID *)pm->sysctrl;
g_sysctrl = NULL;
}
pm->sysctrl = NULL;
LOS_IntRestore(intSave);
if (freeNode != NULL) {
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, freeNode);
}
return LOS_OK;
}
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_INVALID_NODE;
}
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node)
{
LosPmCB *pm = &g_pmCB;
if (node == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
switch (type) {
case LOS_PM_TYPE_DEVICE:
return OsPmDeviceUnregister(pm, (LosPmDevice *)node);
case LOS_PM_TYPE_TICK_TIMER:
return OsPmTickTimerUnregister(pm, (LosPmTickTimer *)node);
case LOS_PM_TYPE_SYSCTRL:
return OsPmSysctrlUnregister(pm, (LosPmSysctrl *)node);
default:
break;
}
return LOS_ERRNO_PM_INVALID_TYPE;
}
VOID LOS_PmWakeSet(VOID)
{
UINT32 intSave;
LosPmCB *pm = &g_pmCB;
intSave = LOS_IntLock();
pm->isWake = TRUE;
LOS_IntRestore(intSave);
return;
}
LOS_SysSleepEnum LOS_PmModeGet(VOID)
{
LOS_SysSleepEnum mode;
LosPmCB *pm = &g_pmCB;
UINT32 intSave = LOS_IntLock();
mode = pm->pmMode;
LOS_IntRestore(intSave);
return mode;
}
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode)
{
UINT32 intSave;
UINT32 taskID;
UINT32 ret;
LosPmCB *pm = &g_pmCB;
INT32 sleepMode = (INT32)mode;
TSK_INIT_PARAM_S taskInitParam = { 0 };
if ((sleepMode < 0) || (sleepMode > LOS_SYS_SHUTDOWN)) {
return LOS_ERRNO_PM_INVALID_MODE;
}
intSave = LOS_IntLock();
if ((mode != LOS_SYS_NORMAL_SLEEP) && (pm->device == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_DEVICE_NULL;
}
if ((mode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightSuspend == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_HANDLER_NULL;
}
if ((mode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepSuspend == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_HANDLER_NULL;
}
if ((mode == LOS_SYS_SHUTDOWN) && (pm->sysctrl->shutdownSuspend == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_HANDLER_NULL;
}
if ((mode == LOS_SYS_DEEP_SLEEP) || (mode == LOS_SYS_SHUTDOWN)) {
if ((pm->tickTimer == NULL) ||
(pm->tickTimer->tickLock == NULL) ||
(pm->tickTimer->tickUnlock == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_TICK_TIMER_NULL;
}
}
pm->pmMode = mode;
LOS_IntRestore(intSave);
if ((mode == LOS_SYS_DEEP_SLEEP) || (mode == LOS_SYS_SHUTDOWN)) {
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsPmTask;
taskInitParam.uwStackSize = LOSCFG_KERNEL_PM_TASK_STACKSIZE;
taskInitParam.pcName = "pm";
taskInitParam.usTaskPrio = LOSCFG_KERNEL_PM_TASK_PTIORITY;
ret = LOS_TaskCreate(&taskID, &taskInitParam);
if (ret != LOS_OK) {
return ret;
}
}
return LOS_OK;
}
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
VOID LOS_PmLockInfoShow(VOID)
{
UINT32 intSave;
LosPmCB *pm = &g_pmCB;
OsPmLockCB *lock = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
PRINTK("Name Count\n\r");
intSave = LOS_IntLock();
while (list != head) {
lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
PRINTK("%-30s%5u\n\r", lock->name, lock->count);
list = list->pstNext;
}
LOS_IntRestore(intSave);
return;
}
#endif
UINT32 LOS_PmLockRequest(const CHAR *name)
{
UINT32 intSave;
UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
LosPmCB *pm = &g_pmCB;
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
OsPmLockCB *listNode = NULL;
OsPmLockCB *lock = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
if (name == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
#endif
intSave = LOS_IntLock();
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
while (list != head) {
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
if (strcmp(name, listNode->name) == 0) {
lock = listNode;
break;
}
list = list->pstNext;
}
if (lock == NULL) {
lock = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(OsPmLockCB));
if (lock == NULL) {
LOS_IntRestore(intSave);
return LOS_NOK;
}
lock->name = (CHAR *)name;
lock->count = 1;
LOS_ListTailInsert(head, &lock->list);
} else if (lock->count < OS_PM_LOCK_MAX) {
lock->count++;
}
#endif
if (pm->lock < OS_PM_LOCK_MAX) {
pm->lock++;
ret = LOS_OK;
}
LOS_IntRestore(intSave);
return ret;
}
UINT32 LOS_PmLockRelease(const CHAR *name)
{
UINT32 intSave;
UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
LosPmCB *pm = &g_pmCB;
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
OsPmLockCB *lock = NULL;
OsPmLockCB *listNode = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
VOID *lockFree = NULL;
if (name == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
#endif
intSave = LOS_IntLock();
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
while (list != head) {
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
if (strcmp(name, listNode->name) == 0) {
lock = listNode;
break;
}
list = list->pstNext;
}
if (lock == NULL) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_NOT_LOCK;
} else if (lock->count > 0) {
lock->count--;
if (lock->count == 0) {
LOS_ListDelete(&lock->list);
lockFree = lock;
}
}
#endif
if (pm->lock > 0) {
pm->lock--;
ret = LOS_OK;
}
LOS_IntRestore(intSave);
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
#endif
return ret;
}
STATIC VOID OsPmSleepTimeSet(UINT64 sleepTime)
{
g_pmSleepTime = sleepTime;
}
UINT32 OsPmInit(VOID)
{
UINT32 ret;
LosPmCB *pm = &g_pmCB;
(VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
LOS_ListInit(&pm->lockList);
#endif
ret = OsSchedRealSleepTimeSet(OsPmSleepTimeSet);
if (ret != LOS_OK) {
return ret;
}
ret = OsPmEnterHandlerSet(OsPmEnter);
if (ret != LOS_OK) {
return ret;
}
g_sysctrl = (LosPmSysctrl *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(LosPmSysctrl));
if (g_sysctrl == NULL) {
return LOS_NOK;
}
(VOID)memset_s(g_sysctrl, sizeof(LosPmSysctrl), 0, sizeof(LosPmSysctrl));
g_sysctrl->normalSuspend = HalEnterSleep;
ret = LOS_PmRegister(LOS_PM_TYPE_SYSCTRL, (VOID *)g_sysctrl);
if (ret != LOS_OK) {
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, g_sysctrl);
g_sysctrl = NULL;
}
return ret;
}
#endif
@@ -0,0 +1,326 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., 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 the copyright holder 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 THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
*/
#ifndef _LOS_PM_H
#define _LOS_PM_H
#include "los_config.h"
#include "los_compiler.h"
#include "los_list.h"
#include "los_error.h"
/**
* @ingroup los_pm
* Pm error code: Invalid low power mode.
*
* Value: 0x02002001
*
*/
#define LOS_ERRNO_PM_INVALID_MODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x01)
/**
* @ingroup los_pm
* Pm error code: Invalid input parameter.
*
* Value: 0x02002002
*
*/
#define LOS_ERRNO_PM_INVALID_PARAM LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x02)
/**
* @ingroup los_pm
* Pm error code: The current mode is unlocked.
*
* Value: 0x02002003
*
*/
#define LOS_ERRNO_PM_NOT_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x03)
/**
* @ingroup los_pm
* Pm error code: The lock limit has been exceeded.
*
* Value: 0x02002004
*
*/
#define LOS_ERRNO_PM_LOCK_LIMIT LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x04)
/**
* @ingroup los_pm
* Pm error code: Invalid device node.
*
* Value: 0x02002005
*
*/
#define LOS_ERRNO_PM_INVALID_NODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x05)
/**
* @ingroup los_pm
* Pm error code: Invalid type.
*
* Value: 0x02002006
*
*/
#define LOS_ERRNO_PM_INVALID_TYPE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x06)
/**
* @ingroup los_pm
* Pm error code: The hook for mode is not implemented.
*
* Value: 0x02002007
*
*/
#define LOS_ERRNO_PM_HANDLER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x07)
/**
* @ingroup los_pm
* Pm error code: Deep and shutdown must implement the Tick Timer related interface.
*
* Value: 0x02002008
*
*/
#define LOS_ERRNO_PM_TICK_TIMER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x08)
/**
* @ingroup los_pm
* Pm error code: Device is not registered.
*
* Value: 0x02002009
*
*/
#define LOS_ERRNO_PM_DEVICE_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x09)
typedef enum {
LOS_SYS_NORMAL_SLEEP = 0,
LOS_SYS_LIGHT_SLEEP,
LOS_SYS_DEEP_SLEEP,
LOS_SYS_SHUTDOWN,
} LOS_SysSleepEnum;
typedef enum {
LOS_PM_TYPE_DEVICE = 0,
LOS_PM_TYPE_TICK_TIMER,
LOS_PM_TYPE_SYSCTRL,
} LOS_PmNodeType;
typedef struct {
UINT32 (*suspend)(UINT32 mode);
VOID (*resume)(UINT32 mode);
} LosPmDevice;
typedef struct {
UINT32 freq; /* The frequency of the low power timer */
VOID (*timerStart)(UINT64); /* Start the low power timer */
VOID (*timerStop)(VOID); /* Stop the low power timer */
UINT64 (*timerCycleGet)(VOID); /* Gets the running time of the low power timer in unit cycle */
VOID (*tickLock)(VOID); /* Pause the system tick timer */
VOID (*tickUnlock)(VOID); /* Restore the system tick timer */
} LosPmTickTimer;
typedef struct {
UINT32 (*normalSuspend)(VOID);
VOID (*normalResume)(VOID);
UINT32 (*lightSuspend)(VOID);
VOID (*lightResume)(VOID);
UINT32 (*deepSuspend)(VOID);
VOID (*deepResume)(VOID);
UINT32 (*shutdownSuspend)(VOID);
VOID (*shutdownResume)(VOID);
} LosPmSysctrl;
/**
* @ingroup los_pm
* @brief Initialize system low power frame.
*
* @par Description:
* This API is used to initialize the system low power frame.
*
* @attention None.
*
* @param None.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see
*/
UINT32 OsPmInit(VOID);
/**
* @ingroup los_pm
* @brief Register a power management node.
*
* @par Description:
* This API is used to register a power management node.
*
* @attention None.
*
* @param type [IN] The types supported by the PM module.
* @param node [IN] power management node.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmUnregister
*/
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node);
/**
* @ingroup los_pm
* @brief Unregister a power management node.
*
* @par Description:
* This API is used to unregister a power management node.
*
* @attention None.
*
* @param type [IN] The types supported by the PM module.
* @param node [IN] power management node.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmRegister
*/
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node);
/**
* @ingroup los_pm
* @brief Set the system wake up flag.
*
* @par Description:
* This API is used to set the system wake-up flag.
*
* @attention None.
*
* @param None.
*
* @retval None.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see
*/
VOID LOS_PmWakeSet(VOID);
/**
* @ingroup los_pm
* @brief Get the low power mode of the current system.
*
* @par Description:
* This API is used to get the low power mode of the current system.
*
* @attention None.
*
* @param None.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmModeSet
*/
LOS_SysSleepEnum LOS_PmModeGet(VOID);
/**
* @ingroup los_pm
* @brief Set low power mode.
*
* @par Description:
* This API is used to set low power mode.
*
* @attention None.
*
* @param mode [IN] low power mode.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmModeGet
*/
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode);
/**
* @ingroup los_pm
* @brief Request to obtain the lock in current mode, so that the system will not enter
* this mode when it enters the idle task next time.
*
* @par Description:
* This API is used to obtain the lock in current mode.
*
* @attention None.
*
* @param name [IN] Who requests the lock.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRelease
*/
UINT32 LOS_PmLockRequest(const CHAR *name);
/**
* @ingroup los_pm
* @brief Release the lock in current mode so that the next time the system enters
* the idle task, it will enter this mode.
*
* @par Description:
* This API is used to release the lock in current mode.
*
* @attention None.
*
* @param name [IN] Who releases the lock.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRequest
*/
UINT32 LOS_PmLockRelease(const CHAR *name);
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
/**
* @ingroup los_pm
* @brief Output the locking information of the pm lock.
*
* @par Description:
* This API is used to output the locking information of the pm lock.
*
* @attention None.
*
* @param None.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRequest
*/
VOID LOS_PmLockInfoShow(VOID);
#endif
#endif