first submission
This commit is contained in:
@@ -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_ */
|
||||
+42
@@ -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_ */
|
||||
+70
@@ -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_ */
|
||||
+65
@@ -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_ */
|
||||
+298
@@ -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_ */
|
||||
+38
@@ -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_ */
|
||||
+79
@@ -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_ */
|
||||
+54
@@ -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_ */
|
||||
+83
@@ -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);
|
||||
+61
@@ -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
|
||||
+188
@@ -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(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
|
||||
SMEMCPY(ðhdr->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(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
|
||||
SMEMCPY(ðhdr->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
|
||||
Reference in New Issue
Block a user