build: W600-SDK importiert, Firmware-Build und Hello am EVK
Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet, Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs (EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# THE VERSION NUMBER
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
|
||||
PROJECT(WMOTA)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
|
||||
# ENABLE ASM
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
|
||||
SET(CMAKE_STATIC_LIBRARY_PREFIX)
|
||||
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
|
||||
|
||||
# C FLAGS
|
||||
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
|
||||
STRING(APPEND CMAKE_C_FLAGS "-DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
|
||||
|
||||
|
||||
# DEBUG ASM FLAGS
|
||||
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
|
||||
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
|
||||
|
||||
# Library sources
|
||||
SET(LIBRARY_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/wm_http_fwup.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/wm_socket_fwup.c"
|
||||
)
|
||||
|
||||
function(ADD_LIB_TARGET LIBTARGET)
|
||||
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
|
||||
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../../Lib/GNU/${LIBTARGET})
|
||||
endfunction()
|
||||
|
||||
ADD_LIB_TARGET(wmota.a)
|
||||
@@ -0,0 +1,237 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "wm_socket_fwup.h"
|
||||
#include "wm_fwup.h"
|
||||
#include "wm_http_fwup.h"
|
||||
#include "wm_debug.h"
|
||||
#include "wm_mem.h"
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT
|
||||
|
||||
#define HTTP_CLIENT_BUFFER_SIZE 2048
|
||||
#define USE_BREAK_POINT_RESUME 1
|
||||
#define RECV_TIMEOUT 5
|
||||
|
||||
|
||||
|
||||
enum ota_state {PREPARE_PACKET, SETUP_LINK_AND_REQ, RECV_RSP, HANDLE_HEADER, HANDLE_BODY, SHUTDOWN_LINK, QUIT_OTA};
|
||||
|
||||
int http_fwup(HTTPParameters ClientParams)
|
||||
{
|
||||
char* Buffer = NULL;
|
||||
char token[32];
|
||||
char headRange[32] = {0};
|
||||
int nRetCode = 0;
|
||||
u32 content_length=0, size=32;
|
||||
u32 partLen;
|
||||
u32 totalLen = 0;
|
||||
u32 recvLen = 0;
|
||||
T_BOOTER *booter;
|
||||
#if USE_BREAK_POINT_RESUME == 0
|
||||
u32 breakFlag = 0;
|
||||
u32 breakLen = 0;
|
||||
#endif
|
||||
struct pbuf *p;
|
||||
HTTP_SESSION_HANDLE pHTTP;
|
||||
enum ota_state now_state = PREPARE_PACKET;
|
||||
|
||||
Buffer = (char*)tls_mem_alloc(HTTP_CLIENT_BUFFER_SIZE);
|
||||
if (!Buffer)
|
||||
return HTTP_CLIENT_ERROR_NO_MEMORY;
|
||||
memset(Buffer, 0, HTTP_CLIENT_BUFFER_SIZE);
|
||||
|
||||
while(1)
|
||||
{
|
||||
switch(now_state)
|
||||
{
|
||||
case PREPARE_PACKET:
|
||||
{
|
||||
memset(token, 0, 32);
|
||||
size = 32;
|
||||
pHTTP = HTTPClientOpenRequest(0);
|
||||
#if USE_BREAK_POINT_RESUME
|
||||
HTTPClientSetVerb(pHTTP,VerbGet);
|
||||
sprintf(headRange, "bytes=%d-", recvLen);
|
||||
if((nRetCode = HTTPClientAddRequestHeaders(pHTTP,"Range", headRange, 1))!= HTTP_CLIENT_SUCCESS){
|
||||
now_state = QUIT_OTA;
|
||||
}
|
||||
#else
|
||||
if( recvLen != 0 ){
|
||||
breakFlag = 1;
|
||||
breakLen = 0;
|
||||
}
|
||||
#endif
|
||||
now_state = SETUP_LINK_AND_REQ;
|
||||
}
|
||||
break;
|
||||
|
||||
case SETUP_LINK_AND_REQ:
|
||||
{
|
||||
if( (nRetCode = HTTPClientSendRequest(pHTTP,ClientParams.Uri,NULL,0,FALSE,0,0)) != HTTP_CLIENT_SUCCESS ){
|
||||
tls_os_time_delay(HZ*2);
|
||||
now_state = SHUTDOWN_LINK;
|
||||
}
|
||||
else
|
||||
now_state = RECV_RSP;
|
||||
}
|
||||
break;
|
||||
|
||||
case RECV_RSP:
|
||||
{
|
||||
if((nRetCode = HTTPClientRecvResponse(pHTTP, RECV_TIMEOUT)) != HTTP_CLIENT_SUCCESS)
|
||||
now_state = SHUTDOWN_LINK;
|
||||
else
|
||||
now_state = HANDLE_HEADER;
|
||||
}
|
||||
break;
|
||||
|
||||
case HANDLE_HEADER:
|
||||
{
|
||||
if((nRetCode = HTTPClientFindFirstHeader(pHTTP, "content-length", (CHAR *)token, &size)) != HTTP_CLIENT_SUCCESS){
|
||||
HTTPClientFindCloseHeader(pHTTP);
|
||||
now_state = SHUTDOWN_LINK;
|
||||
}
|
||||
else
|
||||
{
|
||||
HTTPClientFindCloseHeader(pHTTP);
|
||||
content_length = atol(strstr(token,":")+1);
|
||||
printf("content_length: %d\n", content_length);
|
||||
now_state = HANDLE_BODY;
|
||||
if(recvLen == 0){
|
||||
nRetCode = socket_fwup_accept(0, ERR_OK);
|
||||
if(nRetCode != ERR_OK)
|
||||
now_state = QUIT_OTA;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HANDLE_BODY:
|
||||
{
|
||||
partLen = 0;
|
||||
while(nRetCode != HTTP_CLIENT_EOS )
|
||||
{
|
||||
u32 nSize = HTTP_CLIENT_BUFFER_SIZE;
|
||||
nRetCode = HTTPClientReadData(pHTTP,Buffer+3,nSize,RECV_TIMEOUT,&nSize);
|
||||
if( recvLen == 0 ){
|
||||
//fileSize = headerSize(fixed: 56) + appCodeSize
|
||||
booter =(T_BOOTER *) (Buffer+3);
|
||||
if (TRUE == tls_fwup_img_header_check(booter))
|
||||
{
|
||||
totalLen = booter->upd_img_len + sizeof(T_BOOTER);
|
||||
//OTA_ResetProgress();
|
||||
//OTA_SetTotalBytes(totalLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
now_state = QUIT_OTA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(nRetCode != HTTP_CLIENT_SUCCESS && nRetCode != HTTP_CLIENT_EOS){
|
||||
now_state = SHUTDOWN_LINK;
|
||||
break;
|
||||
}
|
||||
#if USE_BREAK_POINT_RESUME == 0
|
||||
if(breakFlag == 1){
|
||||
breakLen += nSize;
|
||||
if(breakLen <= recvLen){
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
Buffer = Buffer+3+nSize-(breakLen-recvLen)-3;
|
||||
nSize = (breakLen-recvLen);
|
||||
breakFlag = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
p = pbuf_alloc(PBUF_TRANSPORT, nSize + 3, PBUF_REF);
|
||||
while( !p){
|
||||
tls_os_time_delay(1);
|
||||
p = pbuf_alloc(PBUF_TRANSPORT, nSize + 3, PBUF_REF);
|
||||
}
|
||||
|
||||
if(recvLen == 0)
|
||||
*(Buffer+0) = SOCKET_FWUP_START;
|
||||
else if(nRetCode == HTTP_CLIENT_EOS && recvLen == (totalLen-nSize))
|
||||
*(Buffer+0) = SOCKET_FWUP_END;
|
||||
else
|
||||
*(Buffer+0) = SOCKET_FWUP_DATA;
|
||||
|
||||
*(Buffer+1) = (nSize>>8) & 0xFF;
|
||||
*(Buffer+2) = nSize & 0xFF;
|
||||
p->payload = Buffer;
|
||||
p->len = p->tot_len = nSize + 3;
|
||||
// Send received data to fwup thread and deal with socket issues.
|
||||
s8 ret = socket_fwup_recv(0, p, ERR_OK);
|
||||
if(ret != ERR_OK){
|
||||
now_state = SHUTDOWN_LINK;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
//OTA_IncrementProgress(nSize);
|
||||
recvLen += nSize;
|
||||
partLen += nSize;
|
||||
//printf("download %d / %d\n", recvLen, totalLen); //Status is being printed in our source
|
||||
if(partLen == content_length){
|
||||
now_state = SHUTDOWN_LINK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (now_state == QUIT_OTA);
|
||||
else
|
||||
now_state = SHUTDOWN_LINK;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHUTDOWN_LINK:
|
||||
{
|
||||
if(pHTTP){
|
||||
HTTPClientCloseRequest(&pHTTP);
|
||||
(recvLen == totalLen)?(now_state = QUIT_OTA):(now_state = PREPARE_PACKET);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//printf("now_state %d\n", now_state);
|
||||
if(now_state == QUIT_OTA)
|
||||
break;
|
||||
}
|
||||
|
||||
tls_mem_free(Buffer);
|
||||
if(pHTTP)
|
||||
HTTPClientCloseRequest(&pHTTP);
|
||||
if(ClientParams.Verbose == TRUE)
|
||||
{
|
||||
printf("\n\nHTTP Client terminated %d (got %d kb)\n\n",nRetCode,(recvLen/ 1024));
|
||||
}
|
||||
if(nRetCode)
|
||||
socket_fwup_err(0, nRetCode);
|
||||
return nRetCode;
|
||||
}
|
||||
|
||||
int t_http_fwup(char *url)
|
||||
{
|
||||
HTTPParameters httpParams;
|
||||
memset(&httpParams, 0, sizeof(HTTPParameters));
|
||||
if (url == NULL)
|
||||
{
|
||||
httpParams.Uri = "http://192.168.1.100:8080/WM_W600_SEC.img";
|
||||
}
|
||||
else
|
||||
{
|
||||
httpParams.Uri = url;
|
||||
}
|
||||
printf("Location: %s\n",httpParams.Uri);
|
||||
httpParams.Verbose = TRUE;
|
||||
return http_fwup(httpParams);
|
||||
}
|
||||
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT && TLS_CONFIG_SOCKET_RAW
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name : wm_http_fwup.h
|
||||
*
|
||||
* Description: Http firmware update header file.
|
||||
*
|
||||
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author : wanghf
|
||||
*
|
||||
* Date : 2014-6-5
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef WM_HTTP_FWUP_H
|
||||
#define WM_HTTP_FWUP_H
|
||||
|
||||
#include "wm_type_def.h"
|
||||
#include "wm_http_client.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Function: http_fwup
|
||||
* Description: Download the firmware from internet by http and upgrade it.
|
||||
*
|
||||
* Input: ClientParams: The parameters of connecting http server.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: 0-success, other- failed
|
||||
*
|
||||
* Date : 2014-6-5
|
||||
****************************************************************************/
|
||||
int http_fwup(HTTPParameters ClientParams);
|
||||
|
||||
#endif //WM_HTTP_FWUP_H
|
||||
@@ -0,0 +1,157 @@
|
||||
#include "wm_config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "wm_debug.h"
|
||||
#include "wm_socket_fwup.h"
|
||||
#include "list.h"
|
||||
#include "wm_fwup.h"
|
||||
#include "wm_sockets.h"
|
||||
#include "wm_mem.h"
|
||||
|
||||
#define SOCKET_FWUP_PACK_SIZE 2048
|
||||
static struct socket_fwup_pack current_pack;
|
||||
static u16 current_offset;
|
||||
static u32 session_id;
|
||||
|
||||
static void free_current_pack()
|
||||
{
|
||||
session_id = 0;
|
||||
if(current_pack.data != NULL)
|
||||
{
|
||||
tls_mem_free(current_pack.data);
|
||||
memset(¤t_pack, 0, sizeof(struct socket_fwup_pack));
|
||||
}
|
||||
}
|
||||
|
||||
s8 socket_fwup_recv(u8 skt_num, struct pbuf *p, s8 err)
|
||||
{
|
||||
u16 copylen;
|
||||
int offset = 0;
|
||||
int ret = 0;
|
||||
do
|
||||
{
|
||||
if(current_pack.operation < SOCKET_FWUP_START)
|
||||
{
|
||||
current_offset = 0;
|
||||
copylen = pbuf_copy_partial(p, ¤t_pack.operation, 1, offset);
|
||||
//TLS_DBGPRT_ERR("operation = %d, p->tot_len = %d\n", current_pack.operation, p->tot_len );
|
||||
offset += copylen;
|
||||
copylen = pbuf_copy_partial(p, ¤t_pack.datalen, 2, offset);
|
||||
//TLS_DBGPRT_ERR("datalen copylen = %d\n", copylen);
|
||||
current_pack.datalen = ntohs(current_pack.datalen);
|
||||
TLS_DBGPRT_ERR("datalen = %d\n", current_pack.datalen);
|
||||
offset += copylen;
|
||||
if(current_pack.operation > SOCKET_FWUP_DATA || current_pack.operation < SOCKET_FWUP_START)
|
||||
{
|
||||
TLS_DBGPRT_ERR("current_pack.operation = %d is invalid\n", current_pack.operation);
|
||||
goto err;//return ERR_ABRT;
|
||||
}
|
||||
if(current_pack.operation == SOCKET_FWUP_START)
|
||||
{
|
||||
session_id = tls_fwup_enter(TLS_FWUP_IMAGE_SRC_WEB);
|
||||
if(session_id == 0)
|
||||
{
|
||||
TLS_DBGPRT_ERR("session_id = %d is invalid\n", session_id);
|
||||
goto err;//return ERR_ABRT;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_pack.datalen == 0)
|
||||
{
|
||||
//tls_socket_close(skt_num);
|
||||
goto err;//return ERR_ABRT;
|
||||
}
|
||||
}
|
||||
else if(current_pack.datalen > 0 && current_pack.datalen <= SOCKET_FWUP_PACK_SIZE)
|
||||
{
|
||||
copylen = pbuf_copy_partial(p, ¤t_pack.data[current_offset], current_pack.datalen-current_offset, offset);
|
||||
//TLS_DBGPRT_INFO("copylen=%d, current_pack.data = %02x%02x%02x%02x%02x%02x", copylen, current_pack.data[0], current_pack.data[1], current_pack.data[2], current_pack.data[3], current_pack.data[4], current_pack.data[5]);
|
||||
offset += copylen;
|
||||
current_offset += copylen;
|
||||
if(current_offset == current_pack.datalen)
|
||||
{
|
||||
ret = tls_fwup_request_sync(session_id, current_pack.data, current_pack.datalen);
|
||||
if(ret != TLS_FWUP_STATUS_OK)
|
||||
{
|
||||
TLS_DBGPRT_ERR("up data error.\n");
|
||||
goto err;//return ERR_ABRT;
|
||||
}
|
||||
|
||||
if(current_pack.operation == SOCKET_FWUP_END)
|
||||
{
|
||||
#if TLS_CONFIG_SOCKET_RAW
|
||||
tls_socket_close(skt_num);
|
||||
#endif
|
||||
tls_fwup_exit(session_id);
|
||||
free_current_pack();
|
||||
break;
|
||||
}
|
||||
current_pack.operation = 0;
|
||||
}
|
||||
}
|
||||
else if(current_pack.datalen == 0)
|
||||
{
|
||||
if(current_pack.operation == SOCKET_FWUP_END)
|
||||
{
|
||||
#if TLS_CONFIG_SOCKET_RAW
|
||||
tls_socket_close(skt_num);
|
||||
#endif
|
||||
tls_fwup_exit(session_id);
|
||||
free_current_pack();
|
||||
break;
|
||||
}
|
||||
current_pack.operation = 0;
|
||||
}
|
||||
}while(offset < p->tot_len);
|
||||
if (p)
|
||||
pbuf_free(p);
|
||||
return ERR_OK;
|
||||
|
||||
err:
|
||||
if (p)
|
||||
pbuf_free(p);
|
||||
return ERR_ABRT;
|
||||
}
|
||||
|
||||
void socket_fwup_err(u8 skt_num, s8 err)
|
||||
{
|
||||
TLS_DBGPRT_INFO("socket num=%d, err= %d\n", skt_num, err);
|
||||
tls_fwup_exit(session_id);
|
||||
free_current_pack();
|
||||
}
|
||||
|
||||
s8 socket_fwup_poll(u8 skt_num)
|
||||
{
|
||||
//printf("socketpoll skt_num : %d\n", skt_num);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
s8 socket_fwup_accept(u8 skt_num, s8 err)
|
||||
{
|
||||
TLS_DBGPRT_INFO("accept socket num=%d, err= %d\n", skt_num, err);
|
||||
if(ERR_OK == err)
|
||||
{
|
||||
//ret = tls_fwup_init();
|
||||
//if(ret == TLS_FWUP_STATUS_EMEM)
|
||||
// return ERR_ABRT;
|
||||
if(session_id == 0 || tls_fwup_current_state(session_id) == TLS_FWUP_STATE_UNDEF)
|
||||
{
|
||||
memset(¤t_pack, 0, sizeof(struct socket_fwup_pack));
|
||||
current_pack.data = tls_mem_alloc(SOCKET_FWUP_PACK_SIZE);
|
||||
if(NULL == current_pack.data)
|
||||
{
|
||||
printf("\nmalloc socket fwup pack fail\n");
|
||||
return ERR_ABRT;
|
||||
}
|
||||
memset(current_pack.data, 0, SOCKET_FWUP_PACK_SIZE);
|
||||
return ERR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
TLS_DBGPRT_ERR("session_id=%d is not current session id\n", session_id);
|
||||
return ERR_ABRT;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef TLS_SOCKET_FWUP_H
|
||||
#define TLS_SOCKET_FWUP_H
|
||||
|
||||
#include "wm_socket.h"
|
||||
|
||||
#define SOCKET_FWUP_PORT 65533
|
||||
|
||||
#define SOCKET_FWUP_START 1
|
||||
#define SOCKET_FWUP_END 2
|
||||
#define SOCKET_FWUP_DATA 3
|
||||
|
||||
struct socket_fwup_pack{
|
||||
u8 operation;
|
||||
u16 datalen;
|
||||
u8 * data;
|
||||
};
|
||||
|
||||
s8 socket_fwup_recv(u8 skt_num, struct pbuf *p, s8 err);
|
||||
void socket_fwup_err(u8 skt_num, s8 err);
|
||||
s8 socket_fwup_poll(u8 skt_num);
|
||||
s8 socket_fwup_accept(u8 skt_num, s8 err);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
# THE VERSION NUMBER
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
|
||||
PROJECT(WMDHCPSERVER)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
|
||||
# ENABLE ASM
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
|
||||
SET(CMAKE_STATIC_LIBRARY_PREFIX)
|
||||
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
|
||||
|
||||
# C FLAGS
|
||||
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
|
||||
STRING(APPEND CMAKE_C_FLAGS " -DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
|
||||
|
||||
|
||||
# DEBUG ASM FLAGS
|
||||
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
|
||||
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
|
||||
|
||||
# Library sources
|
||||
SET(LIBRARY_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dhcp_server.c"
|
||||
)
|
||||
|
||||
function(ADD_LIB_TARGET LIBTARGET)
|
||||
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
|
||||
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../../Lib/GNU/${LIBTARGET})
|
||||
endfunction()
|
||||
|
||||
ADD_LIB_TARGET(wmdhcpserver.a)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,163 @@
|
||||
/**************************************************************************
|
||||
* File Name : dhcp_server.h
|
||||
* Author :
|
||||
* Version :
|
||||
* Date :
|
||||
* Description :
|
||||
*
|
||||
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef __DHCP_SERVER_H_175137__
|
||||
#define __DHCP_SERVER_H_175137__
|
||||
|
||||
#include "wm_config.h"
|
||||
|
||||
#if TLS_CONFIG_AP
|
||||
#include "wm_sockets.h"
|
||||
|
||||
#define DHCPS_ERR_SUCCESS 0
|
||||
#define DHCPS_ERR_LINKDOWN -1
|
||||
#define DHCPS_ERR_PARAM -2
|
||||
#define DHCPS_ERR_MEM -3
|
||||
#define DHCPS_ERR_NOT_BIND -4
|
||||
#define DHCPS_ERR_NOT_FOUND -5
|
||||
#define DHCPS_ERR_INACTIVE -6
|
||||
|
||||
#define DHCPS_HISTORY_CLIENT_NUM 8
|
||||
|
||||
#define DHCP_DEFAULT_LEASE_TIME 7200 /* 2 Hours. */
|
||||
#define DHCP_DEFAULT_LEASE_TIME_MS 7200000 /* 7200000ms */
|
||||
#define DHCP_TICK_TIME 1000 /* 1s. */
|
||||
#define DHCP_DEFFAULT_TIMEOUT 10 /* 500ms */
|
||||
|
||||
#define DHCP_HWTYPE_ETHERNET 1
|
||||
|
||||
/* udp port number of dhcp. */
|
||||
#define DHCP_CLIENT_UDP_PORT 68
|
||||
#define DHCP_SERVER_UDP_PORT 67
|
||||
|
||||
/* Magic number in DHCP packet. */
|
||||
#define DHCP_MAGIC 0x63825363
|
||||
|
||||
#define DHCP_OP_REQUEST 1
|
||||
#define DHCP_OP_REPLY 2
|
||||
|
||||
#define DHCP_OPTION_ID_PAD 0
|
||||
#define DHCP_OPTION_ID_SUBNET_MASK 1
|
||||
#define DHCP_OPTION_ID_DEF_GW 3
|
||||
#define DHCP_OPTION_ID_DNS_SERVER 6
|
||||
#define DHCP_OPTION_ID_LEASE_TIME 51
|
||||
#define DHCP_OPTION_ID_MSG_TYPE 53
|
||||
#define DHCP_OPTION_ID_SERVER_ID 54
|
||||
#define DHCP_OPTION_ID_REQ_IP_ADDR 50
|
||||
#define DHCP_OPTION_ID_END 255
|
||||
|
||||
#define DHCP_MSG_DISCOVER 1
|
||||
#define DHCP_MSG_OFFER 2
|
||||
#define DHCP_MSG_REQUEST 3
|
||||
#define DHCP_MSG_DECLINE 4
|
||||
#define DHCP_MSG_ACK 5
|
||||
#define DHCP_MSG_NAK 6
|
||||
#define DHCP_MSG_RELEASE 7
|
||||
#define DHCP_MSG_INFORM 8
|
||||
|
||||
#ifdef INT8U
|
||||
#undef INT8U
|
||||
#endif
|
||||
typedef unsigned char INT8U;
|
||||
|
||||
#ifdef INT8S
|
||||
#undef INT8S
|
||||
#endif
|
||||
typedef signed char INT8S;
|
||||
|
||||
#ifdef INT16U
|
||||
#undef INT16U
|
||||
#endif
|
||||
typedef unsigned short INT16U;
|
||||
|
||||
#ifdef INT32U
|
||||
#undef INT32U
|
||||
#endif
|
||||
typedef unsigned int INT32U;
|
||||
|
||||
typedef enum __DHCP_CLIENT_STATE
|
||||
{
|
||||
DHCP_CLIENT_STATE_IDLE=0,
|
||||
DHCP_CLIENT_STATE_SELECT,
|
||||
DHCP_CLIENT_STATE_REQUEST,
|
||||
DHCP_CLIENT_STATE_BIND
|
||||
}DHCP_CLIENT_STATE;
|
||||
|
||||
typedef struct __DHCP_CLIENT
|
||||
{
|
||||
DHCP_CLIENT_STATE State;
|
||||
INT32U Timeout;
|
||||
/* Attention!!! MUST BE __align(4) */
|
||||
ip_addr_t IpAddr;
|
||||
INT8U MacAddr[6];
|
||||
INT32U Lease;
|
||||
}DHCP_CLIENT, *PDHCP_CLIENT;
|
||||
|
||||
typedef struct __DHCP_SERVER
|
||||
{
|
||||
INT8U Enable;
|
||||
struct udp_pcb * Socket;
|
||||
/* Attention!!! MUST BE __align(4) */
|
||||
ip_addr_t ServerIpAddr;
|
||||
ip_addr_t StartIpAddr;
|
||||
ip_addr_t SubnetMask;
|
||||
ip_addr_t GateWay;
|
||||
ip_addr_t Dns1;
|
||||
ip_addr_t Dns2;
|
||||
INT32U LeaseTime;
|
||||
DHCP_CLIENT Clients[DHCPS_HISTORY_CLIENT_NUM];
|
||||
}DHCP_SERVER, *PDHCP_SERVER;
|
||||
|
||||
#define DHCPS_HADDR_SIZE 16
|
||||
#define DHCPS_SNAME_SIZE 64
|
||||
#define DHCPS_FILENAME_SIZE 128
|
||||
#define DHCPS_OPTIONS_LEN 312
|
||||
typedef struct __DHCP_MSG
|
||||
{
|
||||
INT8U Op;
|
||||
INT8U HType;
|
||||
INT8U HLen;
|
||||
INT8U HOps;
|
||||
|
||||
INT32U Xid;
|
||||
|
||||
INT16U Secs;
|
||||
INT16U Flags;
|
||||
|
||||
INT32U Ciaddr;
|
||||
|
||||
INT32U Yiaddr;
|
||||
|
||||
INT32U Siaddr;
|
||||
|
||||
INT32U Giaddr;
|
||||
|
||||
INT8U Chaddr[DHCPS_HADDR_SIZE];
|
||||
|
||||
INT8U Sname[DHCPS_SNAME_SIZE];
|
||||
|
||||
INT8U File[DHCPS_FILENAME_SIZE];
|
||||
|
||||
INT32U Magic;
|
||||
|
||||
INT8U Options[DHCPS_OPTIONS_LEN - 4];
|
||||
}DHCP_MSG, *PDHCP_MSG;
|
||||
|
||||
INT8S DHCPS_Start(struct netif *Netif);
|
||||
void DHCPS_Stop(void);
|
||||
INT8S DHCPS_ClientDelete(INT8U * MacAddr);
|
||||
void DHCPS_RecvCb(void *Arg, struct udp_pcb *Pcb, struct pbuf *P, ip_addr_t *Addr, INT16U Port);
|
||||
void DHCPS_SetDns(INT8U numdns, INT32U dns);
|
||||
ip_addr_t *DHCPS_GetIpByMac(const INT8U *mac_addr);
|
||||
INT8U *DHCPS_GetMacByIp(const ip_addr_t *ipaddr);
|
||||
#endif
|
||||
#endif /* __DHCP_SERVER_H_175137__ */
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# THE VERSION NUMBER
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
|
||||
PROJECT(WMDNSSERVER)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
|
||||
# ENABLE ASM
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
|
||||
SET(CMAKE_STATIC_LIBRARY_PREFIX)
|
||||
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
|
||||
|
||||
# C FLAGS
|
||||
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
|
||||
STRING(APPEND CMAKE_C_FLAGS "-DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
|
||||
|
||||
|
||||
# DEBUG ASM FLAGS
|
||||
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
|
||||
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
|
||||
|
||||
# Library sources
|
||||
SET(LIBRARY_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dns_server.c"
|
||||
)
|
||||
|
||||
function(ADD_LIB_TARGET LIBTARGET)
|
||||
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
|
||||
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../../Lib/GNU/${LIBTARGET})
|
||||
endfunction()
|
||||
|
||||
ADD_LIB_TARGET(wmdnsserver.a)
|
||||
@@ -0,0 +1,390 @@
|
||||
/**************************************************************************
|
||||
* File Name : dns_server.c
|
||||
* Author :
|
||||
* Version :
|
||||
* Date :
|
||||
* Description :
|
||||
*
|
||||
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef WM_W600
|
||||
#include <assert.h>
|
||||
#else
|
||||
#ifndef assert
|
||||
#define assert(n)
|
||||
#endif
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tls_common.h"
|
||||
#include "wm_mem.h"
|
||||
#include "wm_debug.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/udp.h"
|
||||
|
||||
#include "netif/ethernetif.h"
|
||||
|
||||
#include "dns_server.h"
|
||||
|
||||
#include "wm_wifi_oneshot.h"
|
||||
|
||||
#if TLS_CONFIG_AP
|
||||
static DNS_SERVER DnsServer;
|
||||
|
||||
static INT32S _DnsCompareName(INT8U * MyDns, INT8U * Query)
|
||||
{
|
||||
INT8U n;
|
||||
|
||||
if((strlen((const char *)Query) - 1) > 32)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
n = *Query++;
|
||||
/* @see RFC 1035 - 4.1.4. Message compression. */
|
||||
if((n & 0xc0) == 0xc0)
|
||||
{
|
||||
/* Compressed name. */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not compressed name. */
|
||||
while(n > 0)
|
||||
{
|
||||
if((*MyDns) != (*Query))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
++Query;
|
||||
++MyDns;
|
||||
--n;
|
||||
};
|
||||
++MyDns;
|
||||
}
|
||||
} while (*Query != 0);
|
||||
|
||||
return ((*(--MyDns) == 0) ? 0 : 1);
|
||||
}
|
||||
|
||||
static void _DNSNameErrGenAndSend(ip_addr_t *Addr, INT16U Port, PDNS_QUERY pDnsQuery, INT8U * QueryName, INT16U TansactionId)
|
||||
{
|
||||
INT32U Len;
|
||||
INT8U * Body;
|
||||
PDNS_HEADER pDnsHeader;
|
||||
struct pbuf * pDnsBuf;
|
||||
INT8U * pDnsReply;
|
||||
|
||||
Len = ((sizeof(DNS_HEADER) + (strlen((const char *)QueryName) + 1) + sizeof(DNS_QUERY) + 3) >> 2) << 2;
|
||||
pDnsReply = tls_mem_alloc(Len);
|
||||
if(pDnsReply == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pDnsHeader = (PDNS_HEADER)pDnsReply;
|
||||
Body = (INT8U *)(pDnsHeader + 1);
|
||||
Len = 0;
|
||||
|
||||
/* Header. */
|
||||
pDnsHeader->TansactionId = TansactionId;
|
||||
pDnsHeader->DnsFlag1 = DNS_FLAG1_RESPONSE;
|
||||
pDnsHeader->DnsFlag2 = DNS_FLAG2_ERR_NAME;
|
||||
pDnsHeader->Quentions = htons(1);
|
||||
pDnsHeader->AnswerRR = 0;
|
||||
pDnsHeader->AuthorityRR = 0;
|
||||
pDnsHeader->AdditionalRR = 0;
|
||||
Len += sizeof(DNS_HEADER);
|
||||
|
||||
/* Querry. */
|
||||
MEMCPY(Body, QueryName, strlen((const char *)QueryName) + 1);
|
||||
Body += strlen((const char *)QueryName) + 1;
|
||||
Len += strlen((const char *)QueryName) + 1;
|
||||
MEMCPY(Body, pDnsQuery, sizeof(DNS_QUERY));
|
||||
Len += sizeof(DNS_QUERY);
|
||||
|
||||
pDnsBuf = pbuf_alloc(PBUF_TRANSPORT, Len, PBUF_RAM);
|
||||
if(pDnsBuf == NULL)
|
||||
{
|
||||
tls_mem_free(pDnsReply);
|
||||
return;
|
||||
}
|
||||
pbuf_take(pDnsBuf, (const void *) pDnsReply, Len);
|
||||
|
||||
/* Send to the client. */
|
||||
udp_sendto(DnsServer.Socket, pDnsBuf, Addr, Port);
|
||||
pbuf_free(pDnsBuf);
|
||||
tls_mem_free(pDnsReply);
|
||||
}
|
||||
|
||||
static void _DNSAnswerGenAndSend(ip_addr_t *Addr, INT16U Port, PDNS_QUERY pDnsQuery, INT8U * QueryName, INT16U TansactionId)
|
||||
{
|
||||
INT32U Len;
|
||||
INT8U * Body;
|
||||
INT32U ServerIpAddr;
|
||||
PDNS_HEADER pDnsHeader;
|
||||
DNS_ANSWER DnsAnswer;
|
||||
struct pbuf * pDnsBuf;
|
||||
INT8U * pDnsReply;
|
||||
INT16U Tmp;
|
||||
|
||||
Len = ((sizeof(DNS_HEADER) + (strlen((const char *)QueryName) + 1) + sizeof(DNS_QUERY) + 2 + sizeof(DNS_ANSWER) + 2 + 4 + 3) >> 2) << 2;
|
||||
pDnsReply = tls_mem_alloc(Len);
|
||||
if(pDnsReply == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pDnsHeader = (PDNS_HEADER)pDnsReply;
|
||||
Body = (INT8U *)(pDnsHeader + 1);
|
||||
Len = 0;
|
||||
|
||||
/* Header. */
|
||||
pDnsHeader->TansactionId = TansactionId;
|
||||
pDnsHeader->DnsFlag1 = DNS_FLAG1_RESPONSE;
|
||||
pDnsHeader->DnsFlag2 = DNS_FLAG2_ERR_NONE;
|
||||
pDnsHeader->Quentions = htons(1);
|
||||
pDnsHeader->AnswerRR = htons(1);
|
||||
pDnsHeader->AuthorityRR = 0;
|
||||
pDnsHeader->AdditionalRR = 0;
|
||||
Len += sizeof(DNS_HEADER);
|
||||
|
||||
/* Querry. */
|
||||
MEMCPY(Body, QueryName, strlen((const char *)QueryName) + 1);
|
||||
Body += strlen((const char *)QueryName) + 1;
|
||||
Len += strlen((const char *)QueryName) + 1;
|
||||
MEMCPY(Body, pDnsQuery, sizeof(DNS_QUERY));
|
||||
Body += sizeof(DNS_QUERY);
|
||||
Len += sizeof(DNS_QUERY);
|
||||
|
||||
/* NAME: provided as offset to first occurence in response. */
|
||||
Tmp = DNS_NAME_OFFSET | sizeof(DNS_HEADER);
|
||||
Tmp = htons(Tmp);
|
||||
MEMCPY(Body, &Tmp, sizeof(INT16U));
|
||||
Body += sizeof(INT16U);
|
||||
Len += sizeof(INT16U);
|
||||
|
||||
/* Answer. */
|
||||
DnsAnswer.Type = htons(DNS_RRTYPE_A);
|
||||
DnsAnswer.Class = htons(DNS_RRCLASS_IN);
|
||||
DnsAnswer.Ttl = htonl(DNS_DEFAULT_TTL);
|
||||
MEMCPY(Body, &DnsAnswer, sizeof(DNS_ANSWER));
|
||||
Body += sizeof(DNS_ANSWER);
|
||||
Len += sizeof(DNS_ANSWER);
|
||||
|
||||
/* Length. */
|
||||
Tmp = htons(4);
|
||||
MEMCPY(Body, &Tmp, sizeof(INT16U));
|
||||
Body += sizeof(INT16U);
|
||||
Len += sizeof(INT16U);
|
||||
|
||||
/* IP Address. */
|
||||
ServerIpAddr = ip_addr_get_ip4_u32(&DnsServer.HostIp);
|
||||
MEMCPY(Body, &ServerIpAddr, 4);
|
||||
Body += 4;
|
||||
Len += 4;
|
||||
|
||||
pDnsBuf = pbuf_alloc(PBUF_TRANSPORT, Len, PBUF_RAM);
|
||||
if(pDnsBuf == NULL)
|
||||
{
|
||||
tls_mem_free(pDnsReply);
|
||||
return;
|
||||
}
|
||||
pbuf_take(pDnsBuf, (const void *) pDnsReply, Len);
|
||||
|
||||
/* Send to the client. */
|
||||
udp_sendto(DnsServer.Socket, pDnsBuf, Addr, Port);
|
||||
pbuf_free(pDnsBuf);
|
||||
tls_mem_free(pDnsReply);
|
||||
}
|
||||
|
||||
/* DNSS_RecvCb */
|
||||
/*-------------------------------------------------------------------------
|
||||
Description:
|
||||
When an incoming DNS message is to me, this function process it and trigger the state machine.
|
||||
|
||||
Arguments:
|
||||
Arg: Pointer to the user supplied argument.
|
||||
Pcb: Pointer to the udp_pcb which received data.
|
||||
P: Pointer to the packet buffer that was received.
|
||||
Addr: The remote IP address from which the packet was received.
|
||||
Port: The remote port from which the packet was received .
|
||||
|
||||
Return Value:
|
||||
None.
|
||||
|
||||
Note:
|
||||
|
||||
-------------------------------------------------------------------------*/
|
||||
void DNSS_RecvCb(void *Arg, struct udp_pcb *Pcb, struct pbuf *P, ip_addr_t *Addr, INT16U Port)
|
||||
{
|
||||
PDNS_HEADER pDnsHeader;
|
||||
DNS_QUERY DnsQuery;
|
||||
//INT16U nQuestions, nAnswers;
|
||||
INT8U * pDnsName;
|
||||
INT8U * pDnsMsg;
|
||||
|
||||
do
|
||||
{
|
||||
pDnsMsg = tls_mem_alloc(P->tot_len);
|
||||
if(pDnsMsg == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pbuf_copy_partial(P, pDnsMsg, P->tot_len, 0);
|
||||
|
||||
pDnsHeader = (PDNS_HEADER)pDnsMsg;
|
||||
|
||||
/* Get the quention number and answer number. */
|
||||
//nQuestions = ntohs(pDnsHeader->Quentions);
|
||||
//nAnswers = ntohs(pDnsHeader->AnswerRR);
|
||||
|
||||
/* Filter out the response frame and the unstandard query frame. */
|
||||
if((pDnsHeader->DnsFlag1 & DNS_FLAG1_RESPONSE) || ((pDnsHeader->DnsFlag1 & (0xf << 3)) != DNS_FLAG1_OPCODE_STANDARD))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Locate the dns name. */
|
||||
pDnsName = (INT8U *)(pDnsHeader + 1);
|
||||
|
||||
/* Get the query class and type. */
|
||||
MEMCPY(&DnsQuery, (pDnsName + strlen((const char *)pDnsName) + 1), sizeof(DnsQuery));
|
||||
|
||||
/* Check the query class and type. */
|
||||
if((DnsQuery.Class != htons(DNS_RRCLASS_IN)) && (DnsQuery.Type != htons(DNS_RRTYPE_A)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ((_DnsCompareName(DnsServer.DnsName, pDnsName) != 0) &&
|
||||
!((1 == 0 /*tls_wifi_get_oneshot_flag()*/) &&
|
||||
(2 == 0 /*tls_wifi_get_oneshot_config_mode()*/)))
|
||||
{
|
||||
/* Not my dns name, so notify the client name error. */
|
||||
#if TLS_CONFIG_AP
|
||||
struct netif *netif = tls_get_netif();
|
||||
if (!netif_is_up(netif))
|
||||
#endif
|
||||
_DNSNameErrGenAndSend(Addr, Port, &DnsQuery, pDnsName, pDnsHeader->TansactionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* My dns name, so send the answer to the client. */
|
||||
_DNSAnswerGenAndSend(Addr, Port, &DnsQuery, pDnsName, pDnsHeader->TansactionId);
|
||||
}
|
||||
}while(0);
|
||||
|
||||
if(pDnsMsg)
|
||||
{
|
||||
tls_mem_free(pDnsMsg);
|
||||
}
|
||||
pbuf_free(P);
|
||||
}
|
||||
|
||||
/* DNSS_Config */
|
||||
/*-------------------------------------------------------------------------
|
||||
Description:
|
||||
This function is used to updata the server's dns name.
|
||||
Arguments:
|
||||
DnsName : Pointer the server's dns name.
|
||||
|
||||
Return Value:
|
||||
The DNS Server error code:
|
||||
DNSS_ERR_SUCCESS - No error
|
||||
DNSS_ERR_PARAM - Input parameter error
|
||||
Note:
|
||||
The length of the DNS name must be less than 32.
|
||||
-------------------------------------------------------------------------*/
|
||||
INT8S DNSS_Config(INT8U * DnsName)
|
||||
{
|
||||
if((DnsName == NULL) || (strlen((const char *)DnsName) > 32))
|
||||
{
|
||||
/* The length of the DNS name must be less than 32. */
|
||||
return DNSS_ERR_PARAM;
|
||||
}
|
||||
|
||||
memset(DnsServer.DnsName, 0, 32);
|
||||
MEMCPY(DnsServer.DnsName, DnsName, strlen((const char *)DnsName));
|
||||
|
||||
return DNSS_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* DNSS_Start */
|
||||
/*-------------------------------------------------------------------------
|
||||
Description:
|
||||
This function is used to start the dns server's service.
|
||||
Arguments:
|
||||
DnsName : Specify the server's dns name
|
||||
Netif: Pointer to the Lwip network interface.
|
||||
|
||||
Return Value:
|
||||
The DNS Server error code:
|
||||
DNSS_ERR_SUCCESS - No error
|
||||
DNSS_ERR_PARAM - Input parameter error
|
||||
DNSS_ERR_MEM - Out of memory
|
||||
DNSS_ERR_LINKDOWN - The NI is inactive
|
||||
Note:
|
||||
The dns server must be started after the network interface was actived.
|
||||
-------------------------------------------------------------------------*/
|
||||
INT8S DNSS_Start(struct netif *Netif, INT8U * DnsName)
|
||||
{
|
||||
if((Netif == NULL) || (strlen((const char *)DnsName) > 32))
|
||||
{
|
||||
return DNSS_ERR_PARAM;
|
||||
}
|
||||
|
||||
if(netif_is_up(Netif) == 0)
|
||||
{
|
||||
return DNSS_ERR_LINKDOWN;
|
||||
}
|
||||
|
||||
memset(&DnsServer, 0, sizeof(DnsServer));
|
||||
|
||||
MEMCPY(DnsServer.DnsName, DnsName, strlen((const char *)DnsName));
|
||||
ip_addr_set(&DnsServer.HostIp, &Netif->ip_addr);
|
||||
|
||||
DnsServer.Socket = udp_new();
|
||||
if(DnsServer.Socket == NULL)
|
||||
{
|
||||
return DNSS_ERR_MEM;
|
||||
}
|
||||
|
||||
/* Set up local and remote port for the pcb. */
|
||||
udp_bind(DnsServer.Socket, IP_ADDR_ANY, DNS_SERVER_PORT);
|
||||
|
||||
/* Set up the recv callback and argument. */
|
||||
udp_recv(DnsServer.Socket, (udp_recv_fn)DNSS_RecvCb, Netif);
|
||||
|
||||
return DNSS_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/* DNSS_Stop */
|
||||
/*-------------------------------------------------------------------------
|
||||
Description:
|
||||
This function is used to stop the dns server's service.
|
||||
Arguments:
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
None.
|
||||
|
||||
Note:
|
||||
|
||||
-------------------------------------------------------------------------*/
|
||||
void DNSS_Stop(void)
|
||||
{
|
||||
if(DnsServer.Socket) udp_remove(DnsServer.Socket);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/**************************************************************************
|
||||
* File Name : dns_server.h
|
||||
* Author :
|
||||
* Version :
|
||||
* Date :
|
||||
* Description :
|
||||
*
|
||||
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
***************************************************************************/
|
||||
#ifndef __DNS_SERVER_H_175233__
|
||||
#define __DNS_SERVER_H_175233__
|
||||
|
||||
#if TLS_CONFIG_AP
|
||||
#define DNSS_ERR_SUCCESS 0
|
||||
#define DNSS_ERR_LINKDOWN 1
|
||||
#define DNSS_ERR_PARAM 2
|
||||
#define DNSS_ERR_MEM 3
|
||||
|
||||
#define DNS_DEFAULT_TTL 3600 /* a day. */
|
||||
|
||||
#define DNS_SERVER_PORT 53
|
||||
|
||||
/* DNS field TYPE used for "Resource Records". */
|
||||
#define DNS_RRTYPE_A 1 /* a host address. */
|
||||
#define DNS_RRTYPE_NS 2 /* an authoritative name server. */
|
||||
#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX). */
|
||||
#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */
|
||||
#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias. */
|
||||
#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority. */
|
||||
#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL). */
|
||||
#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL). */
|
||||
#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL). */
|
||||
#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL). */
|
||||
#define DNS_RRTYPE_WKS 11 /* a well known service description. */
|
||||
#define DNS_RRTYPE_PTR 12 /* a domain name pointer. */
|
||||
#define DNS_RRTYPE_HINFO 13 /* host information. */
|
||||
#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information. */
|
||||
#define DNS_RRTYPE_MX 15 /* mail exchange. */
|
||||
#define DNS_RRTYPE_TXT 16 /* text strings. */
|
||||
|
||||
/* DNS field CLASS used for "Resource Records". */
|
||||
#define DNS_RRCLASS_IN 1 /* the Internet */
|
||||
#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs).*/
|
||||
#define DNS_RRCLASS_CH 3 /* the CHAOS class. */
|
||||
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87].*/
|
||||
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit. */
|
||||
|
||||
/* DNS protocol flags */
|
||||
#define DNS_FLAG1_RESPONSE 0x80
|
||||
#define DNS_FLAG1_OPCODE_STATUS 0x10
|
||||
#define DNS_FLAG1_OPCODE_INVERSE 0x08
|
||||
#define DNS_FLAG1_OPCODE_STANDARD 0x00
|
||||
#define DNS_FLAG1_AUTHORATIVE 0x04
|
||||
#define DNS_FLAG1_TRUNC 0x02
|
||||
#define DNS_FLAG1_RD 0x01
|
||||
#define DNS_FLAG2_RA 0x80
|
||||
#define DNS_FLAG2_ERR_MASK 0x0f
|
||||
#define DNS_FLAG2_ERR_NONE 0x00
|
||||
#define DNS_FLAG2_ERR_NAME 0x03
|
||||
|
||||
#define DNS_NAME_OFFSET 0xC000
|
||||
|
||||
#ifdef INT8U
|
||||
#undef INT8U
|
||||
#endif
|
||||
typedef unsigned char INT8U;
|
||||
|
||||
#ifdef INT8S
|
||||
#undef INT8S
|
||||
#endif
|
||||
typedef signed char INT8S;
|
||||
|
||||
#ifdef INT16U
|
||||
#undef INT16U
|
||||
#endif
|
||||
typedef unsigned short INT16U;
|
||||
|
||||
#ifdef INT32U
|
||||
#undef INT32U
|
||||
#endif
|
||||
typedef unsigned int INT32U;
|
||||
|
||||
#ifdef INT32S
|
||||
#undef INT32S
|
||||
#endif
|
||||
typedef signed int INT32S;
|
||||
|
||||
typedef struct __DNS_SERVER
|
||||
{
|
||||
struct udp_pcb * Socket;
|
||||
INT8U DnsName[32];
|
||||
/* Attention!!! MUST BE __align(4) */
|
||||
ip_addr_t HostIp;
|
||||
}DNS_SERVER;
|
||||
|
||||
typedef struct __DNS_HEADER
|
||||
{
|
||||
INT16U TansactionId;
|
||||
INT8U DnsFlag1;
|
||||
INT8U DnsFlag2;
|
||||
INT16U Quentions;
|
||||
INT16U AnswerRR;
|
||||
INT16U AuthorityRR;
|
||||
INT16U AdditionalRR;
|
||||
}DNS_HEADER, *PDNS_HEADER;
|
||||
|
||||
typedef struct _DNS_QUERY
|
||||
{
|
||||
INT16U Type;
|
||||
INT16U Class;
|
||||
}DNS_QUERY, *PDNS_QUERY;
|
||||
|
||||
typedef struct __DNS_ANSWER
|
||||
{
|
||||
INT16U Type;
|
||||
INT16U Class;
|
||||
INT32U Ttl;
|
||||
}DNS_ANSWER, *PDNS_ANSWER;
|
||||
|
||||
void DNSS_RecvCb(void *Arg, struct udp_pcb *Pcb, struct pbuf *P, ip_addr_t *Addr, INT16U Port);
|
||||
INT8S DNSS_Config(INT8U * DnsName);
|
||||
INT8S DNSS_Start(struct netif *Netif, INT8U * DnsName);
|
||||
void DNSS_Stop(void);
|
||||
#endif
|
||||
#endif /* __DNS_SERVER_H_175233__ */
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# THE VERSION NUMBER
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
|
||||
PROJECT(WMHTTPCLIENT)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
|
||||
# ENABLE ASM
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
|
||||
SET(CMAKE_STATIC_LIBRARY_PREFIX)
|
||||
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
|
||||
|
||||
# C FLAGS
|
||||
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
|
||||
STRING(APPEND CMAKE_C_FLAGS "-DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
|
||||
|
||||
|
||||
# DEBUG ASM FLAGS
|
||||
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
|
||||
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
|
||||
|
||||
# Library sources
|
||||
SET(LIBRARY_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClient.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClientAuth.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClientString.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/HTTPClientWrapper.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/wm_httpclient_task.c"
|
||||
)
|
||||
|
||||
function(ADD_LIB_TARGET LIBTARGET)
|
||||
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
|
||||
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../../Lib/GNU/${LIBTARGET})
|
||||
endfunction()
|
||||
|
||||
ADD_LIB_TARGET(wmhttpclient.a)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,318 @@
|
||||
|
||||
#ifndef _HTTP_CLIENT
|
||||
#define _HTTP_CLIENT
|
||||
|
||||
#include "wm_config.h"
|
||||
#include "HTTPClientWrapper.h"
|
||||
#include "HTTPClientCommon.h"
|
||||
#include "wm_http_client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTP API global definitions
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef _HTTP_BUILD_AMT
|
||||
#define CMSI_HTTPCLIENT_PROTOCOL_GUID {0x471b2c0e, 0x6137, 0x4d55, 0x92, 0x36, 0xdd, 0x0f, 0xdb, 0xc2, 0x52, 0xfb}
|
||||
#endif
|
||||
|
||||
// Debug hook
|
||||
// #define _HTTP_DEBUGGING_ // Simply dumps more debugging data to the console
|
||||
|
||||
// API Version
|
||||
#define HTTP_CLIENT_VERSION_MINOR 0
|
||||
#define HTTP_CLIENT_VERSION_MAJOR 1
|
||||
|
||||
// Global default sizes
|
||||
#define HTTP_CLIENT_MAX_SEND_RECV_HEADERS 1024 // Maximum Send and receive buffers size
|
||||
#define HTTP_CLIENT_INIT_SEND_RECV_HEADERS 2048 // If we can resize the buffers this would be the initial size
|
||||
|
||||
#define HTTP_CLIENT_MAX_USERNAME_LENGTH 16 // Maximum length the user name (host and proxy authentication)
|
||||
#define HTTP_CLIENT_MAX_PASSWORD_LENGTH 16 // Maximum length for the password
|
||||
// Maximum length for the base 64 encoded credentials (twice the size of the user name and password max parameters)
|
||||
#define HTTP_CLIENT_MAX_64_ENCODED_CRED ((HTTP_CLIENT_MAX_USERNAME_LENGTH + HTTP_CLIENT_MAX_PASSWORD_LENGTH) * 2) + 4
|
||||
#define HTTP_CLIENT_MAX_CHUNK_HEADER 64 // Maximum length for the received chunk header (hex - string) size
|
||||
#define HTTP_CLIENT_MAX_PROXY_HOST_LENGTH 64 // Maximum length for the proxy host name
|
||||
#define HTTP_CLIENT_MAX_TOKEN_LENGTH 512 // Maximum length for an HTTP token data (authentication header elements)
|
||||
#define HTTP_CLIENT_MAX_TOKEN_NAME_LENGTH 32 // Maximum length for an HTTP authorization token name ("qop")
|
||||
#define HTTP_CLIENT_MAX_HEADER_SEARCH_CLUE 1024 // Maximum length for a search clue string (Headers searching)
|
||||
#define HTTP_CLIENT_ALLOW_HEAD_VERB 0 // Can we use the HTTP HEAD verb in our outgoing requests?
|
||||
|
||||
#define HTTP_CLIENT_MEMORY_RESIZABLE FALSE // Permission to dynamically resize the headers buffer
|
||||
#define HTTP_CLIENT_MEMORY_RESIZE_FACTOR 16 // Factor for memory resizing operation
|
||||
|
||||
#define HTTP_CLIENT_DEFAULT_PORT 80 // Default HTTP port
|
||||
#define HTTP_CLIENT_DEFAULT_SSL_PORT 443 // Default HTTPS port
|
||||
#define HTTP_CLIENT_DEFAULT_VERB 0 // GET
|
||||
#define HTTP_CLIENT_DEFAULT_VER "HTTP/1.1" // We will send this in the outgoing header
|
||||
#define HTTP_CLIENT_DEFAULT_PROXY_VER "HTTP/1.0" // We will send this in the outgoing header (proxy)
|
||||
#define HTTP_CLIENT_DEFAULT_AGENT "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
|
||||
#define HTTP_CLIENT_DEFAULT_TIMEOUT 30 // Default timeout in seconds
|
||||
#define HTTP_CLIENT_DEFAULT_KEEP_ALIVE 30 // Default Keep-alive value in seconds
|
||||
#define HTTP_CLIENT_DEFAULT_DIGEST_AUTH "MD5" // This is for bypassing a known bug in AMT05..
|
||||
#define HTTP_CLIENT_DEFAULT_PROXY_AUTH AuthSchemaBasic // Basic
|
||||
|
||||
#define HTTP_CLIENT_CRLF "\r\n" // End of line macro
|
||||
#define HTTP_CLIENT_CRLFX2 "\r\n\r\n" // Double End of line macro
|
||||
|
||||
// HTTP Session internal API flags
|
||||
// Note: Not intended to be set the by the API user
|
||||
#define HTTP_CLIENT_FLAG_SECURE 0x00000010 // The session is secured using TLS
|
||||
#define HTTP_CLIENT_FLAG_URLANDPORT 0x00000020 // Url has a port within
|
||||
#define HTTP_CLIENT_FLAG_URLHTTPS 0x00000040 // Url has a https prefix
|
||||
#define HTTP_CLIENT_FLAG_USINGPROXY 0x00000080 // Operation will be performed using a proxy server
|
||||
#define HTTP_CLIENT_FLAG_CHUNKED 0x00000100 // The incoming data is chunked
|
||||
|
||||
// HTTP Status codes
|
||||
#define HTTP_STATUS_OK 200 // The request has succeeded
|
||||
#define HTTP_STATUS_UNAUTHORIZED 401 // The request requires user authentic
|
||||
#define HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED 407 // The client must first authenticate itself with the proxy
|
||||
|
||||
// Redirection (Note: there are more 30x codes, those are the most popular)
|
||||
#define HTTP_STATUS_OBJECT_MOVED 302 // Page redirection notification
|
||||
#define HTTP_STATUS_OBJECT_MOVED_PERMANENTLY 301 // Page redirection notification
|
||||
#define HTTP_STATUS_CONTINUE 100 // Page continue message
|
||||
|
||||
|
||||
// MIN AMX macro
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
// HTTP timeout macro for selecting the default value if the caller passed 0 (no timeout) to the function
|
||||
#define HTTP_TIMEOUT(nTimeout) (((nTimeout) > (0)) ? (nTimeout * HZ) : (HTTP_CLIENT_DEFAULT_TIMEOUT * HZ))
|
||||
|
||||
// 32 bit alignment macro
|
||||
#define ALIGN(size) ((size & 0xfffffffc) + ((size & 3) ? 4 : 0))
|
||||
|
||||
|
||||
#ifdef _HTTP_DEBUGGING_
|
||||
typedef VOID _stdcall E_HTTPDebug(const char *,const char*,UINT32,char *,...); // HTTPDebug hook function
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTP API internals structures
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Generic parameter structure contains a pointer to the buffer and its length
|
||||
|
||||
typedef struct _HTTP_PARAM
|
||||
{
|
||||
|
||||
CHAR *pParam;
|
||||
UINT32 nLength;
|
||||
|
||||
} HTTP_PARAM;
|
||||
|
||||
// HTTP socket events
|
||||
typedef struct _HTTP_CONNECTION
|
||||
{
|
||||
|
||||
fd_set FDRead; // socket read event
|
||||
fd_set FDWrite; // socket write event
|
||||
fd_set FDError; // socket error event
|
||||
INT32 HttpSocket; // The underling socket
|
||||
UINT32 HttpStartTime; // Time stamp for the session
|
||||
UINT32 HttpClientPort; // For client side binding
|
||||
BOOL TlsNego; // TLS negotiation flag
|
||||
|
||||
} HTTP_CONNECTION;
|
||||
|
||||
// Request URL
|
||||
typedef struct _HTTP_URL
|
||||
{
|
||||
|
||||
HTTP_PARAM UrlBsee; // a pointer and length to the "http" section of the URL
|
||||
HTTP_PARAM UrlHost; // a pointer and length to the host section of the URL
|
||||
HTTP_PARAM UrlPort; // a pointer and length to the PORT (if was specified section)
|
||||
HTTP_PARAM UrlRequest; // a pointer and length of the request section of the URL
|
||||
UINT16 nPort; // the PORT that we should use (could be default or the one found within the URL)
|
||||
CHAR* Url; // a buffer for the URL
|
||||
|
||||
}HTTP_URL;
|
||||
// HTTP headers (incoming and outgoing)
|
||||
typedef struct _HTTP_HEADERS
|
||||
{
|
||||
|
||||
HTTP_PARAM HeadersBuffer; // a pointer and length of the complete Headers (in\out) buffer
|
||||
HTTP_PARAM HeadersOut; // a pointer and length of the outgoing HTTP headers
|
||||
HTTP_PARAM HeadersIn; // a pointer and length of the incoming headers
|
||||
HTTP_PARAM HeaderSearch; // Index and pointer for the header search functions
|
||||
HTTP_VERB HttpVerb; // the HTTP verb that was used in the session
|
||||
HTTP_VERB HttpLastVerb; // the HTTP verb that was last transmited to the server
|
||||
CHAR *SearchClue;
|
||||
CHAR Verb[16]; // the actual string buffer of the HTTP verb
|
||||
|
||||
|
||||
}HTTP_HEADERS;
|
||||
|
||||
// HTTP headers (parsed headers information)
|
||||
typedef struct _HTTP_HEADERS_INFO
|
||||
{
|
||||
HTTP_PARAM HttpRedirectURL; // Stores the redirection URL if we got a 301 or 303 return code
|
||||
UINT32 nHTTPStatus; // the HTTP status code (200 401 407 act')
|
||||
UINT32 nHTTPContentLength; // the Content length if specified of the returned data
|
||||
UINT32 nHTTPPostContentLength;// the Content-Length of the POSTed data (if known)
|
||||
BOOL Connection; // True = Keep alive or undefined, False = Closed
|
||||
BOOL ValidHeaders; // a flag that indicates if the incoming header ware parsed OK and found to be valid
|
||||
BOOL HaveCredentials; // a flag that indicates if we have credentials for the session
|
||||
CHAR HTTPVersion[16]; // HTTP version string buffer (for example: "HTTP 1.1")
|
||||
|
||||
}HTTP_HEADERS_INFO;
|
||||
|
||||
// Authentication parameters that ware extracted from the incoming headers
|
||||
typedef struct _HTTP_AUTH_HEADER
|
||||
{
|
||||
|
||||
HTTP_PARAM AuthHeader; // the pointer and length of the authentication header
|
||||
UINT32 HTTP_AUTH_SCHEMA; // Its schema (could be any of the supported)
|
||||
|
||||
}HTTP_AUTH_HEADER;
|
||||
// Proxy related data
|
||||
typedef struct _HTTP_PROXY
|
||||
{
|
||||
CHAR* ProxyHost;
|
||||
CHAR* ProxtUser;
|
||||
CHAR* ProxyPassword;
|
||||
UINT16 nProxyPort;
|
||||
CHAR AuthSchemaName[16]; // The authentication schema name (for string comperission)
|
||||
HTTP_AUTH_SCHEMA ProxyAuthSchema;
|
||||
|
||||
}HTTP_PROXY;
|
||||
|
||||
// HTTP User credentials
|
||||
typedef struct _HTTP_CREDENTIALS
|
||||
{
|
||||
|
||||
CHAR* CredUser;
|
||||
CHAR* CredPassword;
|
||||
CHAR AuthSchemaName[16]; // The authentication schema name (for string comperission)
|
||||
HTTP_AUTH_SCHEMA CredAuthSchema; // The schema that calle has selected for the session
|
||||
BOOL Authentication; // a flag that indicates that this session has requested a user authentication
|
||||
|
||||
}HTTP_CREDENTIALS;
|
||||
// HTTP Counters
|
||||
typedef struct _HTTP_COUNTERS
|
||||
{
|
||||
|
||||
UINT32 nRecivedHeaderLength; // Bytes count of the incoming header
|
||||
UINT32 nRecivedBodyLength; // Bytes count of the incoming body length
|
||||
UINT32 nRecivedChunkLength; // The next chunk length in bytes
|
||||
UINT32 nBytesToNextChunk; // How many bytes we have to read until we can expect the next chunk
|
||||
UINT32 nActionStartTime; // Operation start time
|
||||
UINT32 nActionTimeout; // Timeout for the session
|
||||
UINT32 nSentChunks; // Count of sent chunks
|
||||
UINT32 nSentBodyBytes; // Count of body bytes that ware sent
|
||||
UINT32 nSentHeaderBytes; // Count of header bytes thhat ware sent
|
||||
|
||||
}HTTP_COUNTERS;
|
||||
|
||||
// HTTP Client Session data
|
||||
typedef struct _HTTP_REQUEST
|
||||
{
|
||||
|
||||
HTTP_URL HttpUrl;
|
||||
HTTP_HEADERS HttpHeaders;
|
||||
HTTP_HEADERS_INFO HttpHeadersInfo;
|
||||
HTTP_AUTH_HEADER HttpAuthHeader;
|
||||
HTTP_PROXY HttpProxy;
|
||||
HTTP_CREDENTIALS HttpCredentials;
|
||||
HTTP_CONNECTION HttpConnection;
|
||||
HTTP_COUNTERS HttpCounters;
|
||||
UINT32 HttpState;
|
||||
UINT32 HttpFlags;
|
||||
#ifdef _HTTP_DEBUGGING_
|
||||
E_HTTPDebug *pDebug;
|
||||
#endif
|
||||
#if TLS_CONFIG_HTTP_CLIENT_SECURE
|
||||
tls_ssl_t *ssl;
|
||||
int ssl_more_data;
|
||||
#endif
|
||||
} HTTP_SESSION, *P_HTTP_SESSION;
|
||||
|
||||
|
||||
/***********move to wm_http_client.h**************
|
||||
// HTTP Type Definitions
|
||||
typedef UINT32 HTTP_SESSION_HANDLE;
|
||||
typedef UINT32 HTTP_CLIENT_SESSION_FLAGS;
|
||||
*/
|
||||
typedef tls_http_session_handle_t HTTP_SESSION_HANDLE;
|
||||
typedef tls_http_session_flags_t HTTP_CLIENT_SESSION_FLAGS;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTP API public interface
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***********move to wm_http_client.h**************
|
||||
HTTP_SESSION_HANDLE HTTPClientOpenRequest (HTTP_CLIENT_SESSION_FLAGS Flags);
|
||||
UINT32 HTTPClientCloseRequest (HTTP_SESSION_HANDLE *pSession);
|
||||
UINT32 HTTPClientSetAuth (HTTP_SESSION_HANDLE pSession, HTTP_AUTH_SCHEMA AuthSchema, void *pReserved);
|
||||
UINT32 HTTPClientSetCredentials (HTTP_SESSION_HANDLE pSession, CHAR *pUserName, CHAR *pPassword);
|
||||
UINT32 HTTPClientSetProxy (HTTP_SESSION_HANDLE pSession, CHAR *pProxyName, UINT16 nPort, CHAR *pUserName, CHAR *pPassword);
|
||||
UINT32 HTTPClientSetVerb (HTTP_SESSION_HANDLE pSession, HTTP_VERB HttpVerb);
|
||||
UINT32 HTTPClientAddRequestHeaders (HTTP_SESSION_HANDLE pSession, CHAR *pHeaderName, CHAR *pHeaderData, BOOL nInsert);
|
||||
UINT32 HTTPClientSendRequest (HTTP_SESSION_HANDLE pSession, CHAR *pUrl, VOID *pData, UINT32 nDataLength, BOOL TotalLength, UINT32 nTimeout,UINT32 nClientPort);
|
||||
UINT32 HTTPClientWriteData (HTTP_SESSION_HANDLE pSession, VOID *pBuffer, UINT32 nBufferLength, UINT32 nTimeout);
|
||||
UINT32 HTTPClientRecvResponse (HTTP_SESSION_HANDLE pSession, UINT32 nTimeout);
|
||||
UINT32 HTTPClientReadData (HTTP_SESSION_HANDLE pSession, VOID *pBuffer, UINT32 nBytesToRead, UINT32 nTimeout, UINT32 *nBytesRecived);
|
||||
UINT32 HTTPClientGetInfo (HTTP_SESSION_HANDLE pSession, HTTP_CLIENT *HTTPClient);
|
||||
|
||||
UINT32 HTTPClientFindFirstHeader (HTTP_SESSION_HANDLE pSession, CHAR *pSearchClue,CHAR *pHeaderBuffer, UINT32 *nLength);
|
||||
UINT32 HTTPClientGetNextHeader (HTTP_SESSION_HANDLE pSession, CHAR *pHeaderBuffer, UINT32 *nLength);
|
||||
UINT32 HTTPClientFindCloseHeader (HTTP_SESSION_HANDLE pSession);
|
||||
*/
|
||||
UINT32 HTTPClientSetLocalConnection (HTTP_SESSION_HANDLE pSession, UINT32 nPort);
|
||||
#ifdef _HTTP_DEBUGGING_
|
||||
UINT32 HTTPClientSetDebugHook (HTTP_SESSION_HANDLE pSession,E_HTTPDebug *pDebug);
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTP API private function
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static UINT32 HTTPIntrnResizeBuffer (P_HTTP_SESSION pHTTPSession, UINT32 nNewSize);
|
||||
static UINT32 HTTPIntrnSetURL (P_HTTP_SESSION pHTTPSession, CHAR *pUrl,UINT32 nUrlLength);
|
||||
static UINT32 HTTPIntrnConnectionClose (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnConnectionOpen (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnGetRemoteHeaders (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnGetRemoteChunkLength (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnSend (P_HTTP_SESSION pHTTPSession, CHAR *pData,UINT32 *nLength);
|
||||
static UINT32 HTTPIntrnRecv (P_HTTP_SESSION pHTTPSession, CHAR *pData,UINT32 *nLength,BOOL PeekOnly);
|
||||
static UINT32 HTTPIntrnParseAuthHeader (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnAuthHandler (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnAuthSendDigest (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnAuthSendBasic (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnAuthenticate (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnHeadersAdd (P_HTTP_SESSION pHTTPSession, CHAR *pHeaderName, UINT32 nNameLength, CHAR *pHeaderData, UINT32 nDataLength);
|
||||
static UINT32 HTTPIntrnHeadersRemove (P_HTTP_SESSION pHTTPSession, CHAR *pHeaderName);
|
||||
static UINT32 HTTPIntrnHeadersReceive (P_HTTP_SESSION pHTTPSession, UINT32 nTimeout);
|
||||
static UINT32 HTTPIntrnHeadersSend (P_HTTP_SESSION pHTTPSession, HTTP_VERB HttpVerb);
|
||||
static UINT32 HTTPIntrnHeadersParse (P_HTTP_SESSION pHTTPSession);
|
||||
static UINT32 HTTPIntrnHeadersFind (P_HTTP_SESSION pHTTPSession, CHAR *pHeaderName, HTTP_PARAM *pParam,BOOL IncommingHeaders,UINT32 nOffset);
|
||||
static UINT32 HTTPIntrnSessionReset (P_HTTP_SESSION pHTTPSession, BOOL EntireSession);
|
||||
static UINT32 HTTPIntrnSessionGetUpTime (VOID);
|
||||
static BOOL HTTPIntrnSessionEvalTimeout (P_HTTP_SESSION pHTTPSession);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_HTTP_CLIENT
|
||||
@@ -0,0 +1,673 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Module Name:
|
||||
// HTTPClientAuth.c
|
||||
//
|
||||
// Abstract: Handle Digest, MD5 and 64 Bit Encoding
|
||||
//
|
||||
// Platform: Any that supports standard C calls
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include "wm_config.h"
|
||||
#include "wm_mem.h"
|
||||
#include "HTTPClientAuth.h"
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_AUTH_BASIC
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPBase64Encoder
|
||||
// Purpose : Converts a given string into a base64 encoded buffer.
|
||||
// Last updated : 01/09/200515/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes :
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HTTPBase64Encoder(unsigned char *out, const unsigned char *in, int inlen)
|
||||
// [OUT] out A pointer to a char to hold the converted string
|
||||
// [IN] in String to convert
|
||||
// [IN] inlen Length of the string to be converted
|
||||
|
||||
{
|
||||
for (; inlen >= 3; inlen -= 3)
|
||||
{
|
||||
*out++ = base64digits[in[0] >> 2];
|
||||
*out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
|
||||
*out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
|
||||
*out++ = base64digits[in[2] & 0x3f];
|
||||
in += 3;
|
||||
}
|
||||
|
||||
if (inlen > 0)
|
||||
{
|
||||
unsigned char fragment;
|
||||
|
||||
*out++ = base64digits[in[0] >> 2];
|
||||
fragment = (in[0] << 4) & 0x30;
|
||||
|
||||
if (inlen > 1)
|
||||
fragment |= in[1] >> 4;
|
||||
|
||||
*out++ = base64digits[fragment];
|
||||
*out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
|
||||
*out++ = '=';
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPBase64Decoder
|
||||
// Purpose : Converts a given base64 string into a bytes buffer.
|
||||
// Last updated : 01/09/200515/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes :
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPBase64Decoder(char *out, const char *in)
|
||||
{ // [OUT] out Where to save the converted string
|
||||
// [IN] in String to convert
|
||||
|
||||
int len = 0;
|
||||
register unsigned char digit1, digit2, digit3, digit4;
|
||||
|
||||
if (in[0] == '+' && in[1] == ' ')
|
||||
in += 2;
|
||||
if (*in == '\r')
|
||||
return(0);
|
||||
|
||||
do {
|
||||
|
||||
digit1 = in[0];
|
||||
if (DECODE64(digit1) == BAD)
|
||||
return(-1);
|
||||
digit2 = in[1];
|
||||
if (DECODE64(digit2) == BAD)
|
||||
return(-1);
|
||||
digit3 = in[2];
|
||||
if (digit3 != '=' && DECODE64(digit3) == BAD)
|
||||
return(-1);
|
||||
digit4 = in[3];
|
||||
if (digit4 != '=' && DECODE64(digit4) == BAD)
|
||||
return(-1);
|
||||
in += 4;
|
||||
*out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
|
||||
++len;
|
||||
if (digit3 != '=')
|
||||
{
|
||||
*out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
|
||||
++len;
|
||||
if (digit4 != '=')
|
||||
{
|
||||
*out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
|
||||
++len;
|
||||
}
|
||||
}
|
||||
} while (*in && *in != '\r' && digit4 != '=');
|
||||
|
||||
return (len);
|
||||
}
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH_BASIC
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Purpose : The following code implements the calculations of H(A1), H(A2),
|
||||
// request-digest and response-digest
|
||||
// Last updated : 01/09/200515/05/2005
|
||||
// Author Name : Public Domain\RFC2617
|
||||
// Notes : Digest Access Authentication
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : GenerateCNonce
|
||||
// Purpose : Generates a 32 byte random hexadecimal string such as "4f6ba982..."
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes :
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HTTPDigestGenerateCNonce(char *outbuff)
|
||||
{
|
||||
int i,num;
|
||||
InitRandomeNumber();
|
||||
for(i = 0; i < 32; i++) {
|
||||
num = GetRandomeNumber();
|
||||
switch(num) {
|
||||
case 0: case 1: case 2: case 3: case 4: case 5:
|
||||
case 6: case 7: case 8: case 9:
|
||||
outbuff[i] = '0' + num;
|
||||
break;
|
||||
case 10: case 11: case 12: case 13: case 14: case 15:
|
||||
outbuff[i] = 'a' + (num-10);
|
||||
break;
|
||||
default:
|
||||
outbuff[i] = 'f';
|
||||
}
|
||||
}
|
||||
outbuff[32] = 0;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : DigestCvtHex
|
||||
// Purpose : CConvert to HEX
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain\RFC2617
|
||||
// Notes :
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void HTTPDigestCvtHex(IN HASH Bin,OUT HASHHEX Hex)
|
||||
{
|
||||
unsigned short i;
|
||||
unsigned char j;
|
||||
|
||||
for (i = 0; i < HASHLEN; i++) {
|
||||
j = (Bin[i] >> 4) & 0xf;
|
||||
if (j <= 9)
|
||||
Hex[i*2] = (j + '0');
|
||||
else
|
||||
Hex[i*2] = (j + 'a' - 10);
|
||||
j = Bin[i] & 0xf;
|
||||
if (j <= 9)
|
||||
Hex[i*2+1] = (j + '0');
|
||||
else
|
||||
Hex[i*2+1] = (j + 'a' - 10);
|
||||
};
|
||||
Hex[HASHHEXLEN] = '\0';
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : DigestCalcHA1
|
||||
// Purpose : Calculate H(A1) as per spec
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain\RFC2617
|
||||
// Notes :
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HTTPDigestCalcHA1(
|
||||
IN int nAlg, /* 0 = MD5, 1 = MD5-Sess */
|
||||
IN char * pszUserName,
|
||||
IN char * pszRealm,
|
||||
IN int nRealmLength,
|
||||
IN char * pszPassword,
|
||||
IN char * pszNonce,
|
||||
IN int nNonceLength,
|
||||
IN char * pszCNonce,
|
||||
OUT HASHHEX SessionKey
|
||||
)
|
||||
{
|
||||
MD5_CTX Md5Ctx;
|
||||
HASH HA1;
|
||||
HASHHEX HASess;
|
||||
HASH HAll;
|
||||
|
||||
HTTPMD5Init(&Md5Ctx);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszUserName, strlen(pszUserName)); //Daniel casting
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszRealm, nRealmLength); //Daniel
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszPassword, strlen(pszPassword)); //Daniel
|
||||
HTTPMD5Final((unsigned char *)HA1, &Md5Ctx);
|
||||
|
||||
if (nAlg == 1) /* MD5-Sess */
|
||||
{
|
||||
HTTPDigestCvtHex(HA1, HASess);
|
||||
HTTPMD5Init(&Md5Ctx);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HASess, HASHHEXLEN);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszNonce, nNonceLength);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszCNonce, strlen(pszCNonce));
|
||||
HTTPMD5Final((unsigned char *)HAll, &Md5Ctx);
|
||||
HTTPDigestCvtHex(HAll, SessionKey);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
HTTPDigestCvtHex(HA1, SessionKey);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : DigestCalcResponse
|
||||
// Purpose : Calculate request-digest/response-digest as per HTTP Digest spec
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain\RFC2617
|
||||
// Notes :
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HTTPDigestCalcResponse(
|
||||
IN HASHHEX HA1, // H(A1)
|
||||
IN char * pszNonce, // nonce from server
|
||||
IN int nNonceLength, // Length of nonce
|
||||
IN char * pszNonceCount, // 8 hex digits
|
||||
IN char * pszCNonce, // client nonce */
|
||||
IN char * pszQop, // qop-value: "", "auth", "auth-int"
|
||||
IN int nQopLength, // qop param length
|
||||
IN char * pszMethod, // method from the request
|
||||
IN char * pszDigestUri, // requested URL
|
||||
IN int nDigestUriLebgth, // Uri Length
|
||||
IN HASHHEX HEntity, // H(entity body) if qop="auth-int"
|
||||
OUT HASHHEX Response // request-digest or response-digest
|
||||
)
|
||||
{
|
||||
MD5_CTX Md5Ctx;
|
||||
HASH HA2;
|
||||
HASH RespHash;
|
||||
HASHHEX HA2Hex;
|
||||
|
||||
// Calculate H(A2)
|
||||
HTTPMD5Init(&Md5Ctx);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszMethod, strlen(pszMethod));
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszDigestUri, nDigestUriLebgth);
|
||||
if (stricmp(pszQop, "auth-int") == 0)
|
||||
{
|
||||
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HEntity, HASHHEXLEN);
|
||||
};
|
||||
HTTPMD5Final((unsigned char *)HA2, &Md5Ctx);
|
||||
HTTPDigestCvtHex(HA2, HA2Hex);
|
||||
|
||||
// Calculate response
|
||||
HTTPMD5Init(&Md5Ctx);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HA1, HASHHEXLEN);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszNonce, nNonceLength);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
if (*pszQop)
|
||||
{
|
||||
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszNonceCount, strlen(pszNonceCount));
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszCNonce, strlen(pszCNonce));
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)pszQop, nQopLength);
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)":", 1);
|
||||
};
|
||||
HTTPMD5Update(&Md5Ctx, (const unsigned char *)HA2Hex, HASHHEXLEN);
|
||||
HTTPMD5Final((unsigned char *)RespHash, &Md5Ctx);
|
||||
HTTPDigestCvtHex(RespHash, Response);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Purpose : This code implements the MD5 message-digest algorithm.
|
||||
// The algorithm is due to Ron Rivest. This code was
|
||||
// written by Colin Plumb in 1993, no copyright is claimed.
|
||||
// This code is in the public domain; do with it what you wish.
|
||||
// Equivalent code is available from RSA Data Security, Inc.
|
||||
// This code has been tested against that, and is equivalent,
|
||||
// except that you don't need to include two pages of legalese
|
||||
// with every copy.
|
||||
// Usage : To compute the message digest of a chunk of bytes, declare an
|
||||
// MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
// needed on buffers full of bytes, and then call MD5Final, which
|
||||
// will fill a supplied 16-byte array with the digest.
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef HIGHFIRST
|
||||
#define HTTPMD5ByteReverse(buf, len) /* Nothing */
|
||||
#else
|
||||
void HTTPMD5ByteReverse(unsigned char *buf, unsigned longs);
|
||||
#ifndef ASM_MD5
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : ByteReverse
|
||||
// Purpose : Little\Big Endian support
|
||||
// Gets :
|
||||
// Returns :
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain
|
||||
// Notes : this code is harmless on little-endian machines.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HTTPMD5ByteReverse(unsigned char *buf, unsigned longs)
|
||||
{
|
||||
UINT32 t;
|
||||
do {
|
||||
t = (UINT32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(UINT32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : MD5Init
|
||||
// Purpose : Initialize the MD5Context structure
|
||||
// Gets : MD5Context structure
|
||||
// Returns :
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain
|
||||
// Notes : Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
// initialization constants.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void HTTPMD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : MD5Update
|
||||
// Purpose : Update the MD5Context structure with the target byte array
|
||||
// Gets : MD5Context structure, buffer and length
|
||||
// Returns :
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain
|
||||
// Notes : Update context to reflect the concatenation of another buffer full of bytes.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HTTPMD5Update(struct MD5Context *ctx, UCHAR const *buf, unsigned len)
|
||||
{
|
||||
UINT32 t;
|
||||
|
||||
// Update bitcount
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((UINT32) len << 3)) < t)
|
||||
ctx->bits[1]++; // Carry from low to high
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data
|
||||
|
||||
// Handle any leading odd-sized chunks
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
MEMCPY(p, buf, len);
|
||||
return;
|
||||
}
|
||||
MEMCPY(p, buf, t);
|
||||
HTTPMD5ByteReverse(ctx->in, 16);
|
||||
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
// Process data in 64-byte chunks
|
||||
|
||||
while (len >= 64) {
|
||||
MEMCPY(ctx->in, buf, 64);
|
||||
HTTPMD5ByteReverse(ctx->in, 16);
|
||||
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
// Handle any remaining bytes of data.
|
||||
|
||||
MEMCPY(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : MD5Final
|
||||
// Purpose : Finalize.
|
||||
// Gets : Output digest structure, MD5Context structure
|
||||
// Returns :
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain
|
||||
// Notes : Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
// 1 0* (64-bit count of bits processed, MSB-first).
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
void HTTPMD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
// Compute number of bytes mod 64
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
// Set the first char of padding to 0x80. This is safe since there is
|
||||
// always at least one byte free
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
// Bytes of padding needed to make 64 bytes
|
||||
count = 64 - 1 - count;
|
||||
|
||||
// Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
// Two lots of padding: Pad the first block to 64 bytes
|
||||
memset(p, 0, count);
|
||||
HTTPMD5ByteReverse(ctx->in, 16);
|
||||
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
|
||||
|
||||
// Now fill the next block with 56 bytes
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
// Pad block to 56 bytes
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
HTTPMD5ByteReverse(ctx->in, 14);
|
||||
|
||||
// Append length in bits and transform
|
||||
((UINT32 *) ctx->in)[14] = ctx->bits[0];
|
||||
((UINT32 *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
HTTPMD5Transform(ctx->buf, (UINT32 *) ctx->in);
|
||||
HTTPMD5ByteReverse((unsigned char *) ctx->buf, 4);
|
||||
MEMCPY(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(ctx)); // In case it's sensitive
|
||||
}
|
||||
|
||||
#ifndef ASM_MD5
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function :
|
||||
// Purpose : The four core functions - F1 is optimized somewhat
|
||||
// Last updated : 15/05/2005
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
// This is the central step in the MD5 algorithm.
|
||||
#ifdef __PUREC__
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f /*(x, y, z)*/ + data, w = w<<s | w>>(32-s), w += x )
|
||||
#else
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : MD5Transform
|
||||
// Purpose : The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
// reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
// the data and converts bytes into longwords for this routine.
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Public Domain
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void HTTPMD5Transform(UINT32 buf[4], UINT32 const in[16])
|
||||
{
|
||||
register UINT32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
#ifdef __PUREC__ // PureC Weirdness... (GG)
|
||||
MD5STEP(F1(b,c,d), a, b, c, d, in[0] + 0xd76aa478L, 7);
|
||||
MD5STEP(F1(a,b,c), d, a, b, c, in[1] + 0xe8c7b756L, 12);
|
||||
MD5STEP(F1(d,a,b), c, d, a, b, in[2] + 0x242070dbL, 17);
|
||||
MD5STEP(F1(c,d,a), b, c, d, a, in[3] + 0xc1bdceeeL, 22);
|
||||
MD5STEP(F1(b,c,d), a, b, c, d, in[4] + 0xf57c0fafL, 7);
|
||||
MD5STEP(F1(a,b,c), d, a, b, c, in[5] + 0x4787c62aL, 12);
|
||||
MD5STEP(F1(d,a,b), c, d, a, b, in[6] + 0xa8304613L, 17);
|
||||
MD5STEP(F1(c,d,a), b, c, d, a, in[7] + 0xfd469501L, 22);
|
||||
MD5STEP(F1(b,c,d), a, b, c, d, in[8] + 0x698098d8L, 7);
|
||||
MD5STEP(F1(a,b,c), d, a, b, c, in[9] + 0x8b44f7afL, 12);
|
||||
MD5STEP(F1(d,a,b), c, d, a, b, in[10] + 0xffff5bb1L, 17);
|
||||
MD5STEP(F1(c,d,a), b, c, d, a, in[11] + 0x895cd7beL, 22);
|
||||
MD5STEP(F1(b,c,d), a, b, c, d, in[12] + 0x6b901122L, 7);
|
||||
MD5STEP(F1(a,b,c), d, a, b, c, in[13] + 0xfd987193L, 12);
|
||||
MD5STEP(F1(d,a,b), c, d, a, b, in[14] + 0xa679438eL, 17);
|
||||
MD5STEP(F1(c,d,a), b, c, d, a, in[15] + 0x49b40821L, 22);
|
||||
|
||||
MD5STEP(F2(b,c,d), a, b, c, d, in[1] + 0xf61e2562L, 5);
|
||||
MD5STEP(F2(a,b,c), d, a, b, c, in[6] + 0xc040b340L, 9);
|
||||
MD5STEP(F2(d,a,b), c, d, a, b, in[11] + 0x265e5a51L, 14);
|
||||
MD5STEP(F2(c,d,a), b, c, d, a, in[0] + 0xe9b6c7aaL, 20);
|
||||
MD5STEP(F2(b,c,d), a, b, c, d, in[5] + 0xd62f105dL, 5);
|
||||
MD5STEP(F2(a,b,c), d, a, b, c, in[10] + 0x02441453L, 9);
|
||||
MD5STEP(F2(d,a,b), c, d, a, b, in[15] + 0xd8a1e681L, 14);
|
||||
MD5STEP(F2(c,d,a), b, c, d, a, in[4] + 0xe7d3fbc8L, 20);
|
||||
MD5STEP(F2(b,c,d), a, b, c, d, in[9] + 0x21e1cde6L, 5);
|
||||
MD5STEP(F2(a,b,c), d, a, b, c, in[14] + 0xc33707d6L, 9);
|
||||
MD5STEP(F2(d,a,b), c, d, a, b, in[3] + 0xf4d50d87L, 14);
|
||||
MD5STEP(F2(c,d,a), b, c, d, a, in[8] + 0x455a14edL, 20);
|
||||
MD5STEP(F2(b,c,d), a, b, c, d, in[13] + 0xa9e3e905L, 5);
|
||||
MD5STEP(F2(a,b,c), d, a, b, c, in[2] + 0xfcefa3f8L, 9);
|
||||
MD5STEP(F2(d,a,b), c, d, a, b, in[7] + 0x676f02d9L, 14);
|
||||
MD5STEP(F2(c,d,a), b, c, d, a, in[12] + 0x8d2a4c8aL, 20);
|
||||
|
||||
MD5STEP(F3(b,c,d), a, b, c, d, in[5] + 0xfffa3942L, 4);
|
||||
MD5STEP(F3(a,b,c), d, a, b, c, in[8] + 0x8771f681L, 11);
|
||||
MD5STEP(F3(d,a,b), c, d, a, b, in[11] + 0x6d9d6122L, 16);
|
||||
MD5STEP(F3(c,d,a), b, c, d, a, in[14] + 0xfde5380cL, 23);
|
||||
MD5STEP(F3(b,c,d), a, b, c, d, in[1] + 0xa4beea44L, 4);
|
||||
MD5STEP(F3(a,b,c), d, a, b, c, in[4] + 0x4bdecfa9L, 11);
|
||||
MD5STEP(F3(d,a,b), c, d, a, b, in[7] + 0xf6bb4b60L, 16);
|
||||
MD5STEP(F3(c,d,a), b, c, d, a, in[10] + 0xbebfbc70L, 23);
|
||||
MD5STEP(F3(b,c,d), a, b, c, d, in[13] + 0x289b7ec6L, 4);
|
||||
MD5STEP(F3(a,b,c), d, a, b, c, in[0] + 0xeaa127faL, 11);
|
||||
MD5STEP(F3(d,a,b), c, d, a, b, in[3] + 0xd4ef3085L, 16);
|
||||
MD5STEP(F3(c,d,a), b, c, d, a, in[6] + 0x04881d05L, 23);
|
||||
MD5STEP(F3(b,c,d), a, b, c, d, in[9] + 0xd9d4d039L, 4);
|
||||
MD5STEP(F3(a,b,c), d, a, b, c, in[12] + 0xe6db99e5L, 11);
|
||||
MD5STEP(F3(d,a,b), c, d, a, b, in[15] + 0x1fa27cf8L, 16);
|
||||
MD5STEP(F3(c,d,a), b, c, d, a, in[2] + 0xc4ac5665L, 23);
|
||||
|
||||
MD5STEP(F4(b,c,d), a, b, c, d, in[0] + 0xf4292244L, 6);
|
||||
MD5STEP(F4(a,b,c), d, a, b, c, in[7] + 0x432aff97L, 10);
|
||||
MD5STEP(F4(d,a,b), c, d, a, b, in[14] + 0xab9423a7L, 15);
|
||||
MD5STEP(F4(c,d,a), b, c, d, a, in[5] + 0xfc93a039L, 21);
|
||||
MD5STEP(F4(b,c,d), a, b, c, d, in[12] + 0x655b59c3L, 6);
|
||||
MD5STEP(F4(a,b,c), d, a, b, c, in[3] + 0x8f0ccc92L, 10);
|
||||
MD5STEP(F4(d,a,b), c, d, a, b, in[10] + 0xffeff47dL, 15);
|
||||
MD5STEP(F4(c,d,a), b, c, d, a, in[1] + 0x85845dd1L, 21);
|
||||
MD5STEP(F4(b,c,d), a, b, c, d, in[8] + 0x6fa87e4fL, 6);
|
||||
MD5STEP(F4(a,b,c), d, a, b, c, in[15] + 0xfe2ce6e0L, 10);
|
||||
MD5STEP(F4(d,a,b), c, d, a, b, in[6] + 0xa3014314L, 15);
|
||||
MD5STEP(F4(c,d,a), b, c, d, a, in[13] + 0x4e0811a1L, 21);
|
||||
MD5STEP(F4(b,c,d), a, b, c, d, in[4] + 0xf7537e82L, 6);
|
||||
MD5STEP(F4(a,b,c), d, a, b, c, in[11] + 0xbd3af235L, 10);
|
||||
MD5STEP(F4(d,a,b), c, d, a, b, in[2] + 0x2ad7d2bbL, 15);
|
||||
MD5STEP(F4(c,d,a), b, c, d, a, in[9] + 0xeb86d391L, 21);
|
||||
#else
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
#endif
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
|
||||
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
|
||||
#ifndef HTTP_CLIENT_AUTH_H
|
||||
#define HTTP_CLIENT_AUTH_H
|
||||
|
||||
#include "HTTPClientString.h" // Cross platform support
|
||||
#if TLS_CONFIG_HTTP_CLIENT_AUTH
|
||||
#include "md5.h"
|
||||
#endif
|
||||
#define HASHLEN 16
|
||||
#define HASHHEXLEN 32
|
||||
#define IN
|
||||
#define OUT
|
||||
|
||||
typedef char HASH[HASHLEN];
|
||||
typedef char HASHHEX[HASHHEXLEN+1];
|
||||
//typedef unsigned long uint32;
|
||||
#undef isascii
|
||||
#define isascii(_Char) ( (unsigned)(_Char) < 0x80 )
|
||||
// Base 64 Related
|
||||
#define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
|
||||
#define BAD 0xFF //-1
|
||||
|
||||
static const char base64digits[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static const char base64val[] = {
|
||||
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
|
||||
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
|
||||
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
|
||||
BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
|
||||
BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD
|
||||
};
|
||||
|
||||
void HTTPBase64Encoder(unsigned char *out, const unsigned char *in, int inlen);
|
||||
int HTTPBase64Decoder(char *out, const char *in);
|
||||
|
||||
|
||||
// Digest Related
|
||||
// Generates a 32 byte random hexadecimal string such as "4f6ba982..."
|
||||
void HTTPDigestGenerateCNonce(char *outbuff);
|
||||
|
||||
// Calculate H(A1) as per HTTP Digest spec
|
||||
void HTTPDigestCalcHA1(
|
||||
IN int nAlg, /* 0 = MD5, 1 = MD5-Sess */
|
||||
IN char * pszUserName,
|
||||
IN char * pszRealm,
|
||||
IN int nRealmLength,
|
||||
IN char * pszPassword,
|
||||
IN char * pszNonce,
|
||||
IN int nNonceLength,
|
||||
IN char * pszCNonce,
|
||||
OUT HASHHEX SessionKey
|
||||
);
|
||||
|
||||
// Calculate request-digest/response-digest as per HTTP Digest spec
|
||||
void HTTPDigestCalcResponse(
|
||||
IN HASHHEX HA1, // H(A1)
|
||||
IN char * pszNonce, // nonce from server
|
||||
IN int nNonceLength, // Length of nonce
|
||||
IN char * pszNonceCount, // 8 hex digits
|
||||
IN char * pszCNonce, // client nonce
|
||||
IN char * pszQop, // qop-value: "", "auth", "auth-int"
|
||||
IN int nQopLength, // qop param length
|
||||
IN char * pszMethod, // method from the request
|
||||
IN char * pszDigestUri, // requested URL
|
||||
IN int nDigestUriLebgth, // Uri Length
|
||||
IN HASHHEX HEntity, // H(entity body) if qop="auth-int"
|
||||
OUT HASHHEX Response // request-digest or response-digest
|
||||
);
|
||||
|
||||
// MD5 structures and functions
|
||||
/*struct MD5Context
|
||||
{
|
||||
u32 buf[4];
|
||||
u32 bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
*/
|
||||
#if TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
|
||||
void HTTPMD5Init (struct MD5Context *context);
|
||||
void HTTPMD5Update (struct MD5Context *context, unsigned char const *buf,unsigned len);
|
||||
void HTTPMD5Final (unsigned char digest[16], struct MD5Context *context);
|
||||
void HTTPMD5Transform (u32 buf[4], u32 const in[16]);
|
||||
#endif
|
||||
|
||||
// This is needed to make RSAREF happy on some MS-DOS compilers.
|
||||
typedef struct MD5Context MD5_CTX;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module Name:
|
||||
// CmsiHTTPClientCommon.h
|
||||
//
|
||||
// Abstract: Coomon structs and types for the HTTP protocol API
|
||||
// Author: Eitan Michaelso
|
||||
// Version: 1.0
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _HTTPCLIENT_PROTOCOL_H_
|
||||
#define _HTTPCLIENT_PROTOCOL_H_
|
||||
#include "wm_type_def.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Global default sizes
|
||||
#define HTTP_CLIENT_MAX_URL_LENGTH 512 // Maximum length for an HTTP Url parameter
|
||||
|
||||
// HTTP Session flags (Public flags)
|
||||
#define HTTP_CLIENT_FLAG_KEEP_ALIVE 0x00000001 // Set the keep alive header
|
||||
#define HTTP_CLIENT_FLAG_SEND_CHUNKED 0x00000002 // The outgoing should chunked
|
||||
#define HTTP_CLIENT_FLAG_NO_CACHE 0x00000004 // Set the no cache header
|
||||
#define HTTP_CLIENT_FLAG_ASYNC 0x00000008 // Currently not implemented
|
||||
|
||||
// HTTP status internal flags
|
||||
#define HTTP_CLIENT_STATE_PRE_INIT 0x00000000 // Starting stage
|
||||
#define HTTP_CLIENT_STATE_INIT 0x00000001 // API was initialized (memory was allocated)
|
||||
#define HTTP_CLIENT_STATE_URL_PARSED 0x00000002 // Url was parsed
|
||||
#define HTTP_CLIENT_STATE_HOST_CONNECTED 0x00000004 // HEAD verb was sent
|
||||
#define HTTP_CLIENT_STATE_HEAD_SENT 0x00000008 // Post verb was sent
|
||||
#define HTTP_CLIENT_STATE_POST_SENT 0x00000010 // HTTP requet was sent
|
||||
#define HTTP_CLIENT_STATE_REQUEST_SENT 0x00000020 // HTTP request was sent
|
||||
#define HTTP_CLIENT_STATE_HEADERS_RECIVED 0x00000040 // Headers ware recived from the server
|
||||
#define HTTP_CLIENT_STATE_HEADERS_PARSED 0x00000080 // HTTP headers ware parsed
|
||||
#define HTTP_CLIENT_STATE_HEADERS_OK 0x00000100 // Headers status was OK
|
||||
|
||||
#endif // _HTTPCLIENT_PROTOCOL_H_
|
||||
@@ -0,0 +1,433 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module Name:
|
||||
// HTTPClientString.c
|
||||
//
|
||||
// Abstract: Helper function (string parsing related) for HTTPClient.c module
|
||||
//
|
||||
// Platform: Any that supports standard C calls
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include "wm_config.h"
|
||||
#include "HTTPClient.h"
|
||||
#include "HTTPClientWrapper.h" // Cross platform support
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPStrInsensitiveCompare
|
||||
// Purpose : Same as strcmp() only case insensitive
|
||||
// Returns : BOOL - TRUE if destination string is identical to the source
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL HTTPStrInsensitiveCompare(const CHAR *pSrc, // [IN] a pointer to the source string
|
||||
const CHAR* pDest, // [IN] a pointer to the string we should search for
|
||||
UINT32 nLength) // [IN] The bytes range we should search in
|
||||
{
|
||||
|
||||
// Lower case comparison
|
||||
UINT32 nPosition;
|
||||
UINT32 nDestLength;
|
||||
const CHAR *pSrcIn, *pDestIn;
|
||||
CHAR a,b;
|
||||
pSrcIn = pSrc;
|
||||
pDestIn = pDest;
|
||||
|
||||
nPosition = 0;
|
||||
nDestLength = strlen(pDest);
|
||||
|
||||
if(nLength == 0)
|
||||
{
|
||||
nLength = strlen(pSrc);
|
||||
}
|
||||
if(nDestLength != nLength)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while(pSrcIn || pDestIn)
|
||||
{
|
||||
|
||||
if(nLength > 0 && nPosition == nLength)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
a = *pSrcIn;
|
||||
b = *pDestIn;
|
||||
|
||||
|
||||
if(*pSrcIn >= 64 && *pSrcIn <= 90)
|
||||
{
|
||||
// Upper case to lower case
|
||||
a = *pSrcIn + 32;
|
||||
}
|
||||
|
||||
if(*pDestIn >= 64 && *pDestIn <= 90)
|
||||
{
|
||||
// Upper case to lower case
|
||||
b = *pDestIn + 32;
|
||||
}
|
||||
|
||||
if(a != b)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pSrcIn++;
|
||||
pDestIn++;
|
||||
nPosition++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPStrExtract
|
||||
// Purpose : Extract a string by placing null in the offset parameter
|
||||
// Returns : a pointer to the new string
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CHAR HTTPStrExtract(CHAR *pParam, // [IN] a pointer to the input parameter
|
||||
UINT32 nOffset, // [IN] the offset position (where we should null terminate the string)
|
||||
CHAR Restore) // [IN] if this is not 0 we should restore it (instead of the null)
|
||||
// and reverse the effect.
|
||||
{
|
||||
CHAR Replaced;
|
||||
|
||||
if(!pParam)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// We should restore
|
||||
if(Restore != 0)
|
||||
{
|
||||
pParam[nOffset] = Restore;
|
||||
return Restore;
|
||||
}
|
||||
else
|
||||
{
|
||||
Replaced = pParam[nOffset];
|
||||
pParam[nOffset] = 0;
|
||||
return Replaced;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPStrSearch
|
||||
// Purpose : Search a string within another and return its pointer and a length
|
||||
// Returns : BOOL - TRUE on success
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL HTTPStrSearch(CHAR *pSrc, // [IN] The source string
|
||||
CHAR *pSearched, // [IN] Parameter to search for
|
||||
UINT32 nOffset, // [IN] Offset from the source string start position
|
||||
UINT32 nScope, // [IN] Length in bytes we should search in
|
||||
HTTP_PARAM *HttpParam) // [IN OUT] The Pointer\Length value that will be returned on success
|
||||
{
|
||||
|
||||
CHAR *pSrcStart;
|
||||
CHAR *pDstStart;
|
||||
CHAR nOrigCharacter;
|
||||
UINT32 nPosition = 0;
|
||||
|
||||
do
|
||||
{
|
||||
pSrcStart = pSrc + nOffset;
|
||||
nOrigCharacter = pSrcStart[nScope];
|
||||
|
||||
// Temporarily null terminate
|
||||
pSrcStart[nScope] = 0;
|
||||
|
||||
pDstStart = strstr(pSrcStart,pSearched);
|
||||
if(!pDstStart)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
nPosition = pDstStart - pSrcStart + 1;
|
||||
|
||||
} while(0);
|
||||
|
||||
// Remove the null termination
|
||||
pSrcStart[nScope] = nOrigCharacter;
|
||||
|
||||
if(!nPosition)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(HttpParam)
|
||||
{
|
||||
|
||||
HttpParam->nLength = nPosition -1;
|
||||
HttpParam->pParam = pSrcStart;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int stricmp(const char *s1, const char *s2)
|
||||
{
|
||||
int len1 = strlen(s1);
|
||||
int len2 = strlen(s2);
|
||||
return HTTPStrInsensitiveCompare(s1, s2, MAX(len1, len2));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPStrCaseStr
|
||||
// Purpose : Same as strstr() only case insensitive
|
||||
// Returns : a pointer to the position of the searched string (or 0 on error)
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CHAR *HTTPStrCaseStr(const char *pSrc,UINT32 nSrcLength,const char *pFind)
|
||||
{
|
||||
const char *ptr = pSrc;
|
||||
const char *ptr2;
|
||||
UINT32 iLength = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(iLength >= nSrcLength)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ptr = strchr(pSrc,toupper((unsigned char)*pFind));
|
||||
ptr2 = strchr(pSrc,tolower((unsigned char)*pFind));
|
||||
if (!ptr)
|
||||
{
|
||||
ptr = ptr2;
|
||||
}
|
||||
if (!ptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (ptr2 && (ptr2 < ptr)) {
|
||||
ptr = ptr2;
|
||||
}
|
||||
if (HTTPStrInsensitiveCompare(ptr,pFind,strlen(pFind)))
|
||||
{
|
||||
return (char *) ptr;
|
||||
}
|
||||
pSrc = ptr+1;
|
||||
iLength++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPStrCaseStr
|
||||
// Purpose :
|
||||
// Gets :
|
||||
// Returns :
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
CHAR* HTTPStrGetToken (CHAR *pSrc, UINT32 nSrcLength, CHAR *pDest, UINT32 *nDestLength)
|
||||
{
|
||||
|
||||
// Get text between the ":" and \r\n or end of string.
|
||||
CHAR *pStart = pSrc;
|
||||
CHAR *pEnd;
|
||||
UINT32 nTokenLength = 0;
|
||||
UINT32 nPosition = 0;
|
||||
|
||||
pStart = strchr(pSrc,':') + 1;
|
||||
if(pStart)
|
||||
{
|
||||
pEnd = pStart ;
|
||||
// First pass, count required space
|
||||
while ((*pEnd) && (*pEnd != '\r') && (*pEnd != '\n'))
|
||||
{
|
||||
if(*pEnd != 0x20)
|
||||
{
|
||||
nTokenLength++;
|
||||
}
|
||||
|
||||
if(nSrcLength && nPosition > nSrcLength)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pEnd++;
|
||||
nPosition++;
|
||||
}
|
||||
|
||||
if(nTokenLength > *(nDestLength))
|
||||
{
|
||||
*(nDestLength) = nTokenLength;
|
||||
pDest = NULL;
|
||||
return pDest;
|
||||
}
|
||||
|
||||
// Second pass copy into the destination buffer
|
||||
pEnd = pStart;
|
||||
*(nDestLength) = nTokenLength;
|
||||
nTokenLength = 0;
|
||||
// First pass, count required space
|
||||
while ((*pEnd) && (*pEnd != '\r') && (*pEnd != '\n'))
|
||||
{
|
||||
if(*pEnd != 0x20)
|
||||
{
|
||||
pDest[nTokenLength++] = *pEnd;
|
||||
}
|
||||
pEnd++;
|
||||
}
|
||||
|
||||
pDest[nTokenLength] = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return pDest;
|
||||
}
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_AUTH_DIGEST
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : HTTPStrGetDigestToken
|
||||
// Purpose :
|
||||
// Gets :
|
||||
// Returns :
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UINT32 HTTPStrGetDigestToken (HTTP_PARAM pParamSrc, CHAR *pSearched, HTTP_PARAM *pParamDest)
|
||||
{
|
||||
|
||||
CHAR Token[HTTP_CLIENT_MAX_TOKEN_NAME_LENGTH];
|
||||
CHAR *pPtrStart, *pPtrEnd = NULL, *pPtrEndSrc;
|
||||
BOOL Brackets = FALSE;
|
||||
|
||||
// Build the searched token
|
||||
memset(Token,0x00,HTTP_CLIENT_MAX_TOKEN_NAME_LENGTH);
|
||||
strcpy(Token,pSearched);
|
||||
strcat(Token,"=");
|
||||
|
||||
// Reset destination values
|
||||
pParamDest->nLength = 0;
|
||||
pParamDest->pParam = 0;
|
||||
|
||||
pPtrEndSrc = pParamSrc.pParam + pParamSrc.nLength;
|
||||
|
||||
pPtrStart = HTTPStrCaseStr(pParamSrc.pParam,pParamSrc.nLength,Token);
|
||||
if(pPtrStart)
|
||||
{
|
||||
// Found the token so jump to the end of it
|
||||
pPtrStart += strlen(Token);
|
||||
// jump passed any spaces that may be
|
||||
while ((*pPtrStart) && (*pPtrStart == 0x20) && (pPtrStart != pPtrEndSrc)) pPtrStart++;
|
||||
// Any Brackets around the string?
|
||||
if(*pPtrStart == 0x22) Brackets = TRUE;
|
||||
|
||||
|
||||
switch (Brackets)
|
||||
{
|
||||
|
||||
case TRUE:
|
||||
// Find the next brackets
|
||||
pPtrStart++;
|
||||
pPtrEnd = pPtrStart;
|
||||
while ((*pPtrEnd) && (*pPtrEnd != 0x22) && (*pPtrEnd != 0x0d) && (*pPtrEnd != 0x0a) && (pPtrStart != pPtrEndSrc)) pPtrEnd++;
|
||||
break;
|
||||
|
||||
case FALSE:
|
||||
// Find the next space or comma (0x2c)
|
||||
pPtrEnd = pPtrStart;
|
||||
while ((*pPtrEnd) && (*pPtrEnd != 0x20) && (*pPtrEnd != 0x2c) && (*pPtrEnd != 0x0d) && (*pPtrEnd != 0x0a) && (pPtrStart != pPtrEndSrc)) pPtrEnd++;
|
||||
break;
|
||||
|
||||
};
|
||||
|
||||
pParamDest->nLength = (pPtrEnd - pPtrStart);
|
||||
pParamDest->pParam = pPtrStart;
|
||||
|
||||
return HTTP_CLIENT_SUCCESS;
|
||||
}
|
||||
return HTTP_CLIENT_ERROR_NO_DIGEST_TOKEN;
|
||||
|
||||
|
||||
}
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Function : HTTPStrHToL
|
||||
// Purpose : Convert a hex string "0x00" to long 0
|
||||
// Gets : a pointer to the Hex string
|
||||
// Last updated : 15/05/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
UINT32 HTTPStrHToL (CHAR * s)
|
||||
{
|
||||
UINT32 i , nn, digit;
|
||||
UINT32 n ;
|
||||
|
||||
n = i = nn = 0;
|
||||
do
|
||||
{
|
||||
if ( isalnum((unsigned char)s[i]) ) {
|
||||
s[i] = toupper((unsigned char)s[i]) ;
|
||||
if (s[i] == 'X') nn=n=0; else {
|
||||
digit = (isalpha((unsigned char)s[i]) ? (s[i] - 'A' + 10) : s[i] - '0') ;
|
||||
if ( digit > 15 ) digit = 15;
|
||||
n = n * 16 + digit;
|
||||
if (n |= 0) nn++;
|
||||
if (nn == 8) break;}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while ( s[i] |= 0 );
|
||||
return n ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Function : HTTPStrLToH
|
||||
// Purpose : Convert a long to hex string 0 to "00"
|
||||
// Gets :
|
||||
// Last updated : 15/05/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CHAR* HTTPStrLToH (CHAR * dest,UINT32 nSrc)
|
||||
{
|
||||
|
||||
char *hex = "0123456789abcdef";
|
||||
INT32 i;
|
||||
|
||||
if (nSrc == 0) {
|
||||
dest[0] = '0';
|
||||
dest[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 28; ((nSrc >> i) & 0xf) == 0; i -= 4);
|
||||
for(; i >= 0u; i -= 4) {
|
||||
*dest++ = hex[(nSrc >> i) & 0xf];
|
||||
}
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef _HTTP_CLIENT_STRING
|
||||
#define _HTTP_CLIENT_STRING
|
||||
|
||||
#include "HTTPClientWrapper.h" // Cross platform support
|
||||
#include "HTTPClient.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTP Api global definitions
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int stricmp(const char *s1, const char *s2) ;
|
||||
BOOL HTTPStrInsensitiveCompare (const CHAR *pSrc, const CHAR* pDest, UINT32 nLength);
|
||||
BOOL HTTPStrSearch (CHAR *pSrc, CHAR *pSearched, UINT32 nOffset, UINT32 nScope,HTTP_PARAM *HttpParam);
|
||||
CHAR HTTPStrExtract (CHAR *pParam,UINT32 nOffset,CHAR Restore);
|
||||
CHAR* HTTPStrCaseStr (const CHAR *pSrc, UINT32 nSrcLength, const CHAR *pFind);
|
||||
CHAR* HTTPStrGetToken (CHAR *pSrc, UINT32 nSrcLength, CHAR *pDest, UINT32 *nDestLength);
|
||||
UINT32 HTTPStrGetDigestToken (HTTP_PARAM pParamSrc, CHAR *pSearched, HTTP_PARAM *pParamDest);
|
||||
UINT32 HTTPStrHToL (CHAR * s);
|
||||
CHAR* HTTPStrLToH (CHAR * dest,UINT32 nSrc);
|
||||
#endif
|
||||
@@ -0,0 +1,754 @@
|
||||
|
||||
#include "lwip/arch.h"
|
||||
#include "HTTPClientWrapper.h"
|
||||
#include "random.h"
|
||||
#include "wm_osal.h"
|
||||
#include "wm_sockets.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "wm_debug.h"
|
||||
#include "HTTPClient.h"
|
||||
#if TLS_CONFIG_HTTP_CLIENT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Stdc: HTTPWrapperIsAscii
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : Same as stdc: isascii
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPWrapperIsAscii(int c)
|
||||
{
|
||||
return (!(c & ~0177));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Stdc: HTTPWrapperToUpper
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : Convert character to uppercase.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPWrapperToUpper(int c)
|
||||
{
|
||||
// -32
|
||||
if(HTTPWrapperIsAscii(c) > 0)
|
||||
{
|
||||
if(c >= 97 && c <= 122)
|
||||
{
|
||||
return (c - 32);
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Stdc: HTTPWrapperToLower
|
||||
// Last updated : 13/06/2006
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : Convert character to lowercase.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPWrapperToLower(int c)
|
||||
{
|
||||
// +32
|
||||
if(HTTPWrapperIsAscii(c) > 0)
|
||||
{
|
||||
if(c >= 65 && c <= 90)
|
||||
{
|
||||
return (c + 32);
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Stdc: isalpha
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : returns nonzero if c is a particular representation of an alphabetic character
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPWrapperIsAlpha(int c)
|
||||
{
|
||||
|
||||
if(HTTPWrapperIsAscii(c) > 0)
|
||||
{
|
||||
if( (c >= 97 && c <= 122) || (c >= 65 && c <= 90))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Stdc: isalnum
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : returns nonzero if c is a particular representation of an alphanumeric character
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPWrapperIsAlNum(int c)
|
||||
{
|
||||
if(HTTPWrapperIsAscii(c) > 0)
|
||||
{
|
||||
|
||||
if(HTTPWrapperIsAlpha(c) > 0)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
if( c >= 48 && c <= 57)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTPWrapper_itoa
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : same as stdc itoa() // hmm.. allmost the same
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* HTTPWrapperItoa(char *s,int a)
|
||||
{
|
||||
|
||||
unsigned int b;
|
||||
if(a > 2147483647)
|
||||
{
|
||||
return 0; // overflow
|
||||
}
|
||||
|
||||
if (a < 0) b = -a, *s++ = '-';
|
||||
else b = a;
|
||||
for(;a;a=a/10) s++;
|
||||
for(*s='\0';b;b=b/10) *--s=b%10+'0';
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTPWrapper_ShutDown
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : Handles parameter changes in the socket shutdown() function in AMT
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
int HTTPWrapperShutDown (int s,int how)
|
||||
{
|
||||
return shutdown(s,how);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTPWrapper_GetSocketError
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : WSAGetLastError Wrapper (Win32 Specific)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPWrapperGetSocketError (int s)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTPWrapper_GetRandomeNumber
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : GetRandom number for Win32 & AMT
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HTTPWrapperInitRandomeNumber()
|
||||
{
|
||||
srand((unsigned int)tls_os_get_time());
|
||||
}
|
||||
|
||||
int HTTPWrapperGetRandomeNumber()
|
||||
{
|
||||
int num;
|
||||
num = (int)(((double) rand()/ ((double)RAND_MAX+1)) * 16);
|
||||
return num;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTPWrapper_GetRTC
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : Get uptime under Win32 & AMT
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
long HTTPWrapperGetUpTime()
|
||||
{
|
||||
|
||||
long lTime = 0;
|
||||
|
||||
lTime = tls_os_get_time();
|
||||
return lTime;
|
||||
|
||||
}
|
||||
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : HTTPWrapper_GetHostByName
|
||||
// Last updated : 15/05/2005
|
||||
// Author Name : Eitan Michaelson
|
||||
// Notes : gethostbyname for Win32 (supports the AMT edition of the function)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned long HTTPWrapperGetHostByName(char *name,unsigned long *address)
|
||||
{
|
||||
HTTP_HOSTNET *HostEntry;
|
||||
int iPos = 0, iLen = 0,iNumPos = 0,iDots =0;
|
||||
long iIPElement;
|
||||
char c = 0;
|
||||
char Num[4];
|
||||
int iHostType = 0; // 0 : numeric IP
|
||||
|
||||
// Check if the name is an IP or host
|
||||
iLen = strlen(name);
|
||||
for(iPos = 0; iPos <= iLen;iPos++)
|
||||
{
|
||||
c = name[iPos];
|
||||
if((c >= 48 && c <= 57) || (c == '.') )
|
||||
{
|
||||
// c is numeric or dot
|
||||
if(c != '.')
|
||||
{
|
||||
// c is numeric
|
||||
if(iNumPos > 3)
|
||||
{
|
||||
iHostType++;
|
||||
break;
|
||||
}
|
||||
Num[iNumPos] = c;
|
||||
Num[iNumPos + 1] = 0;
|
||||
iNumPos ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
iNumPos = 0;
|
||||
iDots++;
|
||||
iIPElement = atol(Num);
|
||||
if(iIPElement > 256 || iDots > 3)
|
||||
{
|
||||
return 0; // error invalid IP
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break; // this is an alpha numeric address type
|
||||
}
|
||||
}
|
||||
|
||||
if(c == 0 && iHostType == 0 && iDots == 3)
|
||||
{
|
||||
iIPElement = atol(Num);
|
||||
if(iIPElement > 256)
|
||||
{
|
||||
return 0; // error invalid IP
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iHostType++;
|
||||
}
|
||||
|
||||
if(iHostType > 0)
|
||||
{
|
||||
|
||||
HostEntry = gethostbyname(name);
|
||||
if(HostEntry)
|
||||
{
|
||||
*(address) = *((u_long*)HostEntry->h_addr_list[0]);
|
||||
|
||||
//*(address) = (unsigned long)HostEntry->h_addr_list[0];
|
||||
return 1; // Error
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0; // OK
|
||||
}
|
||||
}
|
||||
|
||||
else // numeric address - no need for DNS resolve
|
||||
{
|
||||
*(address) = inet_addr(name);
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_SECURE
|
||||
#define ALLOW_ANON_CONNECTIONS 1
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int HTTPWrapperSSLNegotiate(HTTP_SESSION_HANDLE pSession,int s,const struct sockaddr *name,int namelen,char *hostname)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
#if 0
|
||||
#define PSLL_PRT printf
|
||||
#else
|
||||
#define PSLL_PRT(x, ...)
|
||||
#endif
|
||||
|
||||
/************************ memory manage ************************/
|
||||
|
||||
|
||||
void *platform_malloc(uint32_t size)
|
||||
{
|
||||
return tls_mem_alloc(size);
|
||||
}
|
||||
|
||||
|
||||
void platform_free(void *ptr)
|
||||
{
|
||||
tls_mem_free(ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************ mutex manage ************************/
|
||||
|
||||
void *platform_mutex_init(void)
|
||||
{
|
||||
tls_os_sem_t *mutex = NULL;
|
||||
|
||||
tls_os_sem_create(&mutex,1);
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
|
||||
void platform_mutex_lock(void *mutex)
|
||||
{
|
||||
tls_os_sem_acquire(mutex,0);
|
||||
}
|
||||
|
||||
|
||||
void platform_mutex_unlock(void *mutex)
|
||||
{
|
||||
tls_os_sem_release(mutex);
|
||||
}
|
||||
|
||||
|
||||
void platform_mutex_destroy(void *mutex)
|
||||
{
|
||||
if (!mutex)
|
||||
return;
|
||||
tls_os_sem_delete(mutex);
|
||||
}
|
||||
|
||||
static int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
|
||||
{
|
||||
return random_get_bytes( output, output_len );
|
||||
}
|
||||
|
||||
static void my_debug( void *ctx, int level, const char *str )
|
||||
{
|
||||
PSLL_PRT("%s", str);
|
||||
}
|
||||
|
||||
static int net_is_blocking( void )
|
||||
{
|
||||
switch( errno )
|
||||
{
|
||||
#if defined EAGAIN
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
return( 1 );
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int net_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
int skt = (int)(long) ctx;
|
||||
#if 0
|
||||
fd_set read_set;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&read_set);
|
||||
FD_SET(skt, &read_set);
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
ret = select(skt + 1, &read_set, NULL, NULL, &tv);
|
||||
if (ret > 0)
|
||||
{
|
||||
if (FD_ISSET(skt, &read_set))
|
||||
{
|
||||
#endif
|
||||
ret = recv( skt, buf, len, 0);
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_is_blocking() != 0 )
|
||||
return( POLARSSL_ERR_NET_WANT_READ );
|
||||
|
||||
if( errno == EPIPE || errno == ECONNRESET )
|
||||
return( POLARSSL_ERR_NET_CONN_RESET );
|
||||
|
||||
if( errno == EINTR )
|
||||
return( POLARSSL_ERR_NET_WANT_READ );
|
||||
|
||||
return( POLARSSL_ERR_NET_RECV_FAILED );
|
||||
}
|
||||
|
||||
#if 0
|
||||
FD_CLR(skt, &read_set);
|
||||
}
|
||||
else
|
||||
{
|
||||
PSLL_PRT("\r\n\r\nssl select no\r\n\r\n");
|
||||
}
|
||||
}
|
||||
else if (0 == ret)
|
||||
{
|
||||
PSLL_PRT("\r\n\r\nssl recv timeout\r\n\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PSLL_PRT("\r\n\r\nssl select error\r\n\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write at most 'len' characters
|
||||
*/
|
||||
static int net_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
{
|
||||
int ret = send( (long) ctx, buf, len, 0);
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( net_is_blocking() != 0 )
|
||||
return( POLARSSL_ERR_NET_WANT_WRITE );
|
||||
|
||||
if( errno == EPIPE || errno == ECONNRESET )
|
||||
return( POLARSSL_ERR_NET_CONN_RESET );
|
||||
|
||||
if( errno == EINTR )
|
||||
return( POLARSSL_ERR_NET_WANT_WRITE );
|
||||
|
||||
return( POLARSSL_ERR_NET_SEND_FAILED );
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
void *platform_ssl_connect(void *tcp_fd,
|
||||
const char *server_cert,
|
||||
int server_cert_len)
|
||||
{
|
||||
int ret;
|
||||
ssl_context *ssl;
|
||||
ssl_session *ssn;
|
||||
x509_cert *cacert = NULL;
|
||||
|
||||
ssl = platform_malloc(sizeof(ssl_context));
|
||||
if (!ssl)
|
||||
return NULL;
|
||||
|
||||
ssn = platform_malloc(sizeof(ssl_session));
|
||||
if (!ssn)
|
||||
{
|
||||
platform_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (server_cert)
|
||||
{
|
||||
cacert = platform_malloc(sizeof(x509_cert));
|
||||
if (!cacert)
|
||||
{
|
||||
platform_free(ssl);
|
||||
platform_free(ssn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(cacert, 0, sizeof(x509_cert));
|
||||
ret = x509parse_crt(cacert, (unsigned char *) server_cert, server_cert_len);
|
||||
if( ret != 0 )
|
||||
{
|
||||
PSLL_PRT( " failed\n ! x509parse_crt returned %d\n\n", ret );
|
||||
platform_free(ssl);
|
||||
platform_free(ssn);
|
||||
if(cacert)
|
||||
platform_free(cacert);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
memset(ssl, 0, sizeof(ssl_context));
|
||||
if( ( ret = ssl_init( ssl ) ) != 0 )
|
||||
{
|
||||
PSLL_PRT( " failed\n ! ssl_init returned %d\n\n", ret );
|
||||
if(cacert)
|
||||
x509_free( cacert );
|
||||
platform_free(ssl);
|
||||
platform_free(ssn);
|
||||
if(cacert)
|
||||
platform_free(cacert);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssl_set_endpoint( ssl, SSL_IS_CLIENT );
|
||||
if (server_cert)
|
||||
ssl_set_authmode( ssl, SSL_VERIFY_REQUIRED );
|
||||
else
|
||||
ssl_set_authmode( ssl, SSL_VERIFY_NONE );
|
||||
|
||||
ssl_set_rng( ssl, ctr_drbg_random, NULL );
|
||||
ssl_set_dbg( ssl, my_debug, NULL);
|
||||
ssl_set_bio( ssl, net_recv, tcp_fd, net_send, tcp_fd );
|
||||
|
||||
ssl_set_ciphersuites( ssl, ssl_default_ciphersuites );
|
||||
|
||||
memset(ssn, 0, sizeof(ssl_session));
|
||||
ssl_set_session( ssl, 1, 600, ssn );
|
||||
|
||||
if (server_cert)
|
||||
ssl_set_ca_chain( ssl, cacert, NULL, NULL);
|
||||
|
||||
while( ( ret = ssl_handshake( ssl ) ) != 0 )
|
||||
{
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
{
|
||||
PSLL_PRT( " failed\n ! ssl_handshake returned %d\n\n", ret );
|
||||
goto fail;
|
||||
}
|
||||
PSLL_PRT("INFO: ssl_handshake returned %d\n\n", ret);
|
||||
}
|
||||
|
||||
if (server_cert)
|
||||
{
|
||||
if( ( ret = ssl_get_verify_result( ssl ) ) != 0 )
|
||||
{
|
||||
PSLL_PRT( "Verifying peer X.509 certificate failed\n" );
|
||||
|
||||
if( ( ret & BADCERT_EXPIRED ) != 0 )
|
||||
PSLL_PRT( " ! server certificate has expired\n" );
|
||||
|
||||
if( ( ret & BADCERT_REVOKED ) != 0 )
|
||||
PSLL_PRT( " ! server certificate has been revoked\n" );
|
||||
|
||||
if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
|
||||
PSLL_PRT( " ! CN mismatch \n");
|
||||
|
||||
if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
|
||||
PSLL_PRT( " ! self-signed or not signed by a trusted CA\n" );
|
||||
|
||||
PSLL_PRT( "\n" );
|
||||
|
||||
ssl_close_notify( ssl );
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
PSLL_PRT( "Verifying X.509 certificate pass.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
//ssl->read_lock = platform_mutex_init();
|
||||
ssl->write_lock = platform_mutex_init();
|
||||
|
||||
//printf("ssl read/write lock 0x%p/0x%p\n", ssl->read_lock, ssl->write_lock);
|
||||
PSLL_PRT("ssl rdwr lock 0x%p\n", ssl->write_lock);
|
||||
|
||||
return ssl;
|
||||
|
||||
fail:
|
||||
if(cacert)
|
||||
x509_free( cacert );
|
||||
ssl_free( ssl );
|
||||
platform_free(ssl);
|
||||
platform_free(ssn);
|
||||
if(cacert)
|
||||
platform_free(cacert);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int platform_ssl_close(void *ssl)
|
||||
{
|
||||
ssl_context *sslt = (ssl_context *)ssl;
|
||||
|
||||
platform_mutex_lock(sslt->write_lock);
|
||||
|
||||
ssl_close_notify( sslt );
|
||||
|
||||
x509_free( sslt->ca_chain );
|
||||
|
||||
platform_free(sslt->ca_chain);
|
||||
|
||||
platform_free(sslt->session);
|
||||
|
||||
platform_mutex_unlock(sslt->write_lock);
|
||||
platform_mutex_destroy(sslt->write_lock);
|
||||
//platform_mutex_destroy(sslt->read_lock);
|
||||
|
||||
ssl_free(sslt);
|
||||
|
||||
platform_free(sslt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int platform_ssl_send(void *ssl, const char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
ssl_context *sslt = (ssl_context *)ssl;
|
||||
|
||||
platform_mutex_lock(sslt->write_lock);
|
||||
|
||||
while( ( ret = ssl_write( sslt, (u8 *)buf, len ) ) <= 0 )
|
||||
{
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
{
|
||||
PSLL_PRT( " failed\n ! ssl_write returned %d, errno %d\n", ret , errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
platform_mutex_unlock(sslt->write_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int platform_ssl_recv(void *ssl, char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
ssl_context *sslt = (ssl_context *)ssl;
|
||||
|
||||
platform_mutex_lock(sslt->write_lock);
|
||||
//platform_mutex_lock(sslt->read_lock);
|
||||
|
||||
do
|
||||
{
|
||||
ret = ssl_read( sslt, (u8 *)buf, len );
|
||||
|
||||
if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
|
||||
continue;
|
||||
|
||||
//if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
|
||||
// break;
|
||||
|
||||
if( ret < 0 )
|
||||
{
|
||||
PSLL_PRT( "failed\n ! ssl_read returned %d, errno %d\n", ret , errno);
|
||||
break;
|
||||
}
|
||||
else if( ret == 0 )
|
||||
{
|
||||
PSLL_PRT("\n\nEOF, errno %d\n\n", errno);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//PSLL_PRT( " %d bytes read\n\n%s", ret, (char *) buf );
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
platform_mutex_unlock(sslt->write_lock);
|
||||
//platform_mutex_unlock(sslt->read_lock);
|
||||
//PSLL_PRT(" <== platform_ssl_recv ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int HTTPWrapperSSLConnect(tls_ssl_t **ssl_p,int fd,const struct sockaddr *name,int namelen,char *hostname)
|
||||
{
|
||||
int rc;
|
||||
tls_ssl_t *ssl = NULL;
|
||||
|
||||
if(name)
|
||||
{
|
||||
char *host_ip = inet_ntoa(((struct sockaddr_in*)name)->sin_addr);
|
||||
|
||||
rc = connect(fd, // Socket
|
||||
name, // Server address
|
||||
sizeof(struct sockaddr));
|
||||
if(rc)
|
||||
{
|
||||
TLS_DBGPRT_ERR("host_ip=%s\n", host_ip);
|
||||
TLS_DBGPRT_ERR("Connection Failed: %d. Exiting\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
ssl = platform_ssl_connect((void *)fd, NULL, 0);
|
||||
|
||||
if(ssl == NULL)
|
||||
return -1;
|
||||
*ssl_p = ssl;
|
||||
return 0;
|
||||
}
|
||||
int HTTPWrapperSSLSend(tls_ssl_t *ssl, int s,char *sndbuf, int len,int flags)
|
||||
{
|
||||
return platform_ssl_send(ssl, sndbuf, len);
|
||||
}
|
||||
|
||||
int HTTPWrapperSSLRecv(tls_ssl_t *ssl,int s,char *buf, int len,int flags)
|
||||
{
|
||||
int ret = platform_ssl_recv(ssl, buf, len);
|
||||
if(ssl->in_msglen > 0)
|
||||
return SOCKET_SSL_MORE_DATA;
|
||||
return ret;
|
||||
}
|
||||
int HTTPWrapperSSLRecvPending(tls_ssl_t *ssl)
|
||||
{
|
||||
return ssl_get_bytes_avail(ssl);
|
||||
}
|
||||
int HTTPWrapperSSLClose(tls_ssl_t *ssl, int s)
|
||||
{
|
||||
if(ssl == NULL)
|
||||
return 0;
|
||||
return platform_ssl_close(ssl);
|
||||
}
|
||||
|
||||
#endif //TLS_CONFIG_USE_POLARSSL
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT_SECURE
|
||||
@@ -0,0 +1,121 @@
|
||||
|
||||
#ifndef HTTP_CLIENT_WRAPPER
|
||||
#define HTTP_CLIENT_WRAPPER
|
||||
|
||||
#include "wm_config.h"
|
||||
#include "lwip/arch.h"
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_SECURE
|
||||
#include "polarssl/config.h"
|
||||
#include "polarssl/ssl.h"
|
||||
#endif
|
||||
// Compilation mode
|
||||
//#define _HTTP_BUILD_WIN32 // Set Windows Build flag
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Microsoft Windows Support
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
//#include <time.h>
|
||||
//#include <winsock.h>
|
||||
|
||||
#include "wm_type_def.h"
|
||||
#include "wm_sockets.h"
|
||||
#include "wm_http_client.h"
|
||||
// Generic types
|
||||
// Sockets (Winsock wrapper)
|
||||
|
||||
#define HTTP_ECONNRESET (ECONNRESET)
|
||||
#define HTTP_EINPROGRESS (EINPROGRESS)
|
||||
#define HTTP_EWOULDBLOCK (EWOULDBLOCK)
|
||||
|
||||
#define SOCKET_ERROR (-1)
|
||||
#define SOCKET_SSL_MORE_DATA (-2)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Functions that are not supported by the AMT stdc framework
|
||||
// So they had to be specificaly added.
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_SECURE
|
||||
typedef ssl_context tls_ssl_t;
|
||||
#endif
|
||||
|
||||
|
||||
// STDC Wrapper implimentation
|
||||
int HTTPWrapperIsAscii (int c);
|
||||
int HTTPWrapperToUpper (int c);
|
||||
int HTTPWrapperToLower (int c);
|
||||
int HTTPWrapperIsAlpha (int c);
|
||||
int HTTPWrapperIsAlNum (int c);
|
||||
char* HTTPWrapperItoa (char *buff,int i);
|
||||
void HTTPWrapperInitRandomeNumber (void);
|
||||
long HTTPWrapperGetUpTime (void);
|
||||
int HTTPWrapperGetRandomeNumber (void);
|
||||
int HTTPWrapperGetSocketError (int s);
|
||||
unsigned long HTTPWrapperGetHostByName (char *name,unsigned long *address);
|
||||
int HTTPWrapperShutDown (int s,int in);
|
||||
// SSL Wrapper prototypes
|
||||
#if TLS_CONFIG_HTTP_CLIENT_SECURE
|
||||
int HTTPWrapperSSLConnect (tls_ssl_t **ssl_p,int s,const struct sockaddr *name,int namelen,char *hostname);
|
||||
int HTTPWrapperSSLNegotiate (tls_http_session_handle_t pSession,int s,const struct sockaddr *name,int namelen,char *hostname);
|
||||
int HTTPWrapperSSLSend (tls_ssl_t *ssl,int s,char *buf, int len,int flags);
|
||||
int HTTPWrapperSSLRecv (tls_ssl_t *ssl,int s,char *buf, int len,int flags);
|
||||
int HTTPWrapperSSLClose (tls_ssl_t *ssl, int s);
|
||||
int HTTPWrapperSSLRecvPending (tls_ssl_t *ssl);
|
||||
#endif
|
||||
// Global wrapper Functions
|
||||
#define IToA HTTPWrapperItoa
|
||||
#define GetUpTime HTTPWrapperGetUpTime
|
||||
#define SocketGetErr HTTPWrapperGetSocketError
|
||||
#define HostByName HTTPWrapperGetHostByName
|
||||
#define InitRandomeNumber HTTPWrapperInitRandomeNumber
|
||||
#define GetRandomeNumber HTTPWrapperGetRandomeNumber
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Section : Global type definitions
|
||||
// Last updated : 01/09/2005
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#ifndef NULL
|
||||
//#define NULL 0
|
||||
//#endif
|
||||
//#define TRUE 1
|
||||
//#define FALSE 0
|
||||
|
||||
#ifdef u_long
|
||||
#undef u_long
|
||||
#endif
|
||||
typedef unsigned long u_long;
|
||||
|
||||
// Global socket structures and definitions
|
||||
#define HTTP_INVALID_SOCKET (-1)
|
||||
typedef struct sockaddr_in HTTP_SOCKADDR_IN;
|
||||
typedef struct timeval HTTP_TIMEVAL;
|
||||
typedef struct hostent HTTP_HOSTNET;
|
||||
typedef struct sockaddr HTTP_SOCKADDR;
|
||||
typedef struct in_addr HTTP_INADDR;
|
||||
|
||||
|
||||
#endif // HTTP_CLIENT_WRAPPER
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef WM_HTTP_COMPILE_FILES
|
||||
#define WM_HTTP_COMPILE_FILES
|
||||
#include "HTTPClient.c"
|
||||
#include "HTTPClientAuth.c"
|
||||
#include "HTTPClientString.c"
|
||||
#include "HTTPClientWrapper.c"
|
||||
#include "wm_httpclient_task.c"
|
||||
#endif
|
||||
@@ -0,0 +1,307 @@
|
||||
#include "wm_type_def.h"
|
||||
#include "wm_http_client.h"
|
||||
#include "HTTPClient.h"
|
||||
#include "HTTPClientWrapper.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientOpenRequest
|
||||
* Description: Allocate memory for a new HTTP Session.
|
||||
*
|
||||
* Input: Flags: HTTP Session internal API flags, 0 should be passed here.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Session handle
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
tls_http_session_handle_t tls_http_client_open_request(tls_http_session_flags_t flags)
|
||||
{
|
||||
return HTTPClientOpenRequest(flags);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientCloseRequest
|
||||
* Description: Closes any active connection and free any used memory.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_close_request(tls_http_session_handle_t *session)
|
||||
{
|
||||
return HTTPClientCloseRequest(session);
|
||||
}
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_AUTH
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientSetAuth
|
||||
* Description: Sets the HTTP authentication schema.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* AuthSchema: HTTP Supported authentication methods.
|
||||
* pReserved: Reserved parameter.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_set_auth(tls_http_session_handle_t session,
|
||||
tls_http_auth_achema_t auth_schema,
|
||||
void *reserved)
|
||||
{
|
||||
return HTTPClientSetAuth(session, (HTTP_AUTH_SCHEMA)auth_schema, reserved);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientSetCredentials
|
||||
* Description: Sets credentials for the target host.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* pUserName: User name.
|
||||
* pPassword: Password.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_set_credentials(tls_http_session_handle_t session,
|
||||
char *user_name, char *password)
|
||||
{
|
||||
return HTTPClientSetCredentials(session, (CHAR *)user_name, (CHAR *)password);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_PROXY
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientSetProxy
|
||||
* Description: Sets all the proxy related parameters.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* pProxyName: The host name.
|
||||
* nPort: The proxy port number.
|
||||
* pUserName: User name for proxy authentication (can be null).
|
||||
* pPassword: User password for proxy authentication (can be null).
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_set_proxy(tls_http_session_handle_t session, char *proxy_name,
|
||||
u16 port, char *user_name, char *password)
|
||||
{
|
||||
return HTTPClientSetProxy(session, (CHAR *)proxy_name, port, (CHAR *)user_name, (CHAR *)password);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientSetVerb
|
||||
* Description: Sets the HTTP verb for the outgoing request.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* HttpVerb: HTTP supported verbs
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_set_verb(tls_http_session_handle_t session, tls_http_verb_t http_verb)
|
||||
{
|
||||
return HTTPClientSetVerb(session, (HTTP_VERB)http_verb);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientAddRequestHeaders
|
||||
* Description: Add headers to the outgoing request.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* pHeaderName: The Headers name
|
||||
* pHeaderData: The headers data
|
||||
* nInsert: Reserved could be any
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_add_request_headers(tls_http_session_handle_t session, char *header_name,
|
||||
char *header_data, bool insert)
|
||||
{
|
||||
return HTTPClientAddRequestHeaders(session, (CHAR *)header_name, (CHAR *)header_data, (BOOL)insert);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientSendRequest
|
||||
* Description: This function builds the request headers, performs a DNS resolution ,
|
||||
* opens the connection (if it was not opened yet by a previous request or if it has closed)
|
||||
* and sends the request headers.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* pUrl: The requested URL
|
||||
* pData: Data to post to the server
|
||||
* nDataLength: Length of posted data
|
||||
* TotalLength: Valid only when http method is post.
|
||||
* TRUE: Post data to http server.
|
||||
* FALSE: In a post request without knowing the total length in advance so return error or use chunking.
|
||||
* nTimeout: Operation timeout
|
||||
* nClientPort: Client side port 0 for none
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_send_request(tls_http_session_handle_t session, char *url, void *data,
|
||||
u32 data_len, bool total_len, u32 time_out, u32 client_port)
|
||||
{
|
||||
return HTTPClientSendRequest(session, (CHAR *)url, data, data_len, (BOOL)total_len, time_out, client_port);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientWriteData
|
||||
* Description: Write data to the remote server.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* pBuffer: Data to write to the server.
|
||||
* nBufferLength: Length of wtitten data.
|
||||
* nTimeout: Timeout for the operation.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_write_data(tls_http_session_handle_t session, void *buffer,
|
||||
u32 buffer_len, u32 time_out)
|
||||
{
|
||||
return HTTPClientWriteData(session, buffer, buffer_len, time_out);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientRecvResponse
|
||||
* Description: Receives the response header on the connection and parses it.
|
||||
* Performs any required authentication.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* nTimeout: Timeout for the operation.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_recv_response(tls_http_session_handle_t session, u32 time_out)
|
||||
{
|
||||
return HTTPClientRecvResponse(session, time_out);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientReadData
|
||||
* Description: Read data from the server. Parse out the chunks data.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* nBytesToRead: The size of the buffer (numbers of bytes to read)
|
||||
* nTimeout: Operation timeout in seconds
|
||||
*
|
||||
* Output: pBuffer: A pointer to a buffer that will be filled with the servers response
|
||||
* nBytesRecived: Count of the bytes that were received in this operation
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_read_data(tls_http_session_handle_t session, void *buffer,
|
||||
u32 bytes_to_read, u32 time_out, u32 *bytes_recived)
|
||||
{
|
||||
return HTTPClientReadData(session, buffer, bytes_to_read, time_out, bytes_recived);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientGetInfo
|
||||
* Description: Fill the users structure with the session information.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
*
|
||||
* Output: HTTPClient: The session information.
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_get_info(tls_http_session_handle_t session, tls_http_client_t *http_client)
|
||||
{
|
||||
return HTTPClientGetInfo(session, http_client);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientFindFirstHeader
|
||||
* Description: Initiate the headr searching functions and find the first header.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
* pSearchClue: Search clue.
|
||||
*
|
||||
* Output: pHeaderBuffer: A pointer to a buffer that will be filled with the header name and value.
|
||||
* nLength: Count of the bytes that were received in this operation.
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_find_first_header(tls_http_session_handle_t session, char *search_clue,
|
||||
char *header_buffer, u32 *length)
|
||||
{
|
||||
return HTTPClientFindFirstHeader(session, (CHAR *)search_clue, (CHAR *)header_buffer, length);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientGetNextHeader
|
||||
* Description: Find the next header.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
*
|
||||
* Output: pHeaderBuffer: A pointer to a buffer that will be filled with the header name and value.
|
||||
* nLength: Count of the bytes that were received in this operation.
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_get_next_header(tls_http_session_handle_t session,
|
||||
char *header_buffer, u32 *length)
|
||||
{
|
||||
return HTTPClientGetNextHeader(session, (CHAR *)header_buffer, length);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function: HTTPClientFindCloseHeader
|
||||
* Description: Terminate a headers search session.
|
||||
*
|
||||
* Input: pSession: HTTP Session handle.
|
||||
*
|
||||
* Output: None
|
||||
*
|
||||
* Return: HTTP Status
|
||||
*
|
||||
* Date : 2014-6-6
|
||||
****************************************************************************/
|
||||
int tls_http_client_find_close_header(tls_http_session_handle_t session)
|
||||
{
|
||||
return HTTPClientFindCloseHeader(session);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#include <string.h>
|
||||
#include "wm_include.h"
|
||||
#include "wm_config.h"
|
||||
#include "wm_http_client.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "wm_wl_task.h"
|
||||
|
||||
#if TLS_CONFIG_HTTP_CLIENT_TASK
|
||||
#define HTTP_CLIENT_STK_SIZE 256
|
||||
static sys_mbox_t http_client_mbox = SYS_MBOX_NULL;
|
||||
static OS_STK httpClientStk[HTTP_CLIENT_STK_SIZE];
|
||||
#define HTTP_CLIENT_BUFFER_SIZE 1024
|
||||
extern u8 pSession_flag;
|
||||
static UINT32 http_snd_req_local(
|
||||
HTTP_SESSION_HANDLE pHTTP, HTTPParameters ClientParams, HTTP_VERB verb, CHAR* pSndData, u32 dataLen,
|
||||
http_client_recv_callback_fn recv_fn)
|
||||
{
|
||||
INT32 nRetCode;
|
||||
UINT32 nSize,nTotal = 0;
|
||||
CHAR* Buffer = NULL;
|
||||
UINT32 nSndDataLen ;
|
||||
CHAR token[32];
|
||||
UINT32 size=32;
|
||||
char *pRecvData=NULL;
|
||||
u32 totallen;
|
||||
do
|
||||
{
|
||||
Buffer = (CHAR*)tls_mem_alloc(HTTP_CLIENT_BUFFER_SIZE);
|
||||
if(Buffer == NULL)
|
||||
{
|
||||
return HTTP_CLIENT_ERROR_NO_MEMORY;
|
||||
}
|
||||
memset(Buffer, 0, HTTP_CLIENT_BUFFER_SIZE);
|
||||
//printf("\nHTTP Client v1.0\n\n");
|
||||
nSndDataLen = (pSndData==NULL ? 0 : dataLen);
|
||||
// Set the Verb
|
||||
nRetCode = HTTPClientSetVerb(pHTTP,verb);
|
||||
if(nRetCode != HTTP_CLIENT_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#if TLS_CONFIG_HTTP_CLIENT_AUTH
|
||||
// Set authentication
|
||||
if(ClientParams.AuthType != AuthSchemaNone)
|
||||
{
|
||||
if((nRetCode = HTTPClientSetAuth(pHTTP,ClientParams.AuthType,NULL)) != HTTP_CLIENT_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Set authentication
|
||||
if((nRetCode = HTTPClientSetCredentials(pHTTP,ClientParams.UserName,ClientParams.Password)) != HTTP_CLIENT_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH
|
||||
#if TLS_CONFIG_HTTP_CLIENT_PROXY
|
||||
// Use Proxy server
|
||||
if(ClientParams.UseProxy == TRUE)
|
||||
{
|
||||
if((nRetCode = HTTPClientSetProxy(pHTTP,ClientParams.ProxyHost,ClientParams.ProxyPort,NULL,NULL)) != HTTP_CLIENT_SUCCESS)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT_PROXY
|
||||
if((nRetCode = HTTPClientSendRequest(pHTTP,ClientParams.Uri,pSndData,nSndDataLen,verb==VerbPost || verb==VerbPut,0,0)) != HTTP_CLIENT_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Retrieve the the headers and analyze them
|
||||
if((nRetCode = HTTPClientRecvResponse(pHTTP,30)) != HTTP_CLIENT_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
memset(token, 0, 32);
|
||||
if((nRetCode = HTTPClientFindFirstHeader(pHTTP, "content-length", token, &size)) != HTTP_CLIENT_SUCCESS)
|
||||
{
|
||||
totallen = HTTP_CLIENT_BUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
totallen = atol(strstr(token,":")+1);
|
||||
|
||||
}
|
||||
HTTPClientFindCloseHeader(pHTTP);
|
||||
//printf("Start to receive data from remote server...\n");
|
||||
// Get the data until we get an error or end of stream code
|
||||
pSession_flag = 0;
|
||||
while(nRetCode == HTTP_CLIENT_SUCCESS || nRetCode != HTTP_CLIENT_EOS)
|
||||
{
|
||||
// Set the size of our buffer
|
||||
nSize = HTTP_CLIENT_BUFFER_SIZE;
|
||||
// Get the data
|
||||
nRetCode = HTTPClientReadData(pHTTP,Buffer,nSize,300,&nSize);
|
||||
if(nRetCode != HTTP_CLIENT_SUCCESS && nRetCode != HTTP_CLIENT_EOS)
|
||||
break;
|
||||
pRecvData = tls_mem_alloc(nSize);
|
||||
if(pRecvData == NULL)
|
||||
{
|
||||
nRetCode = HTTP_CLIENT_ERROR_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
memcpy(pRecvData, Buffer, nSize);
|
||||
recv_fn(pHTTP, pRecvData, totallen, nSize);
|
||||
}
|
||||
} while(0); // Run only once
|
||||
if(Buffer)
|
||||
tls_mem_free(Buffer);
|
||||
if(pHTTP)
|
||||
HTTPClientCloseRequest(&pHTTP);
|
||||
if(ClientParams.Verbose == TRUE)
|
||||
{
|
||||
printf("\n\nHTTP Client terminated %d (got %d kb)\n\n",nRetCode,(nTotal/ 1024));
|
||||
}
|
||||
return nRetCode;
|
||||
}
|
||||
|
||||
static void http_client_rx(void *sdata)
|
||||
{
|
||||
int ret;
|
||||
void *msg;
|
||||
http_client_msg *http_msg;
|
||||
for(;;)
|
||||
{
|
||||
sys_arch_mbox_fetch(&http_client_mbox, (void **)&msg, 0);
|
||||
http_msg = (http_client_msg *)msg;
|
||||
ret = http_snd_req_local(http_msg->pSession,
|
||||
http_msg->param,
|
||||
http_msg->method,
|
||||
http_msg->sendData,
|
||||
http_msg->dataLen,
|
||||
http_msg->recv_fn);
|
||||
//printf("http_client_rx ret=%d\n", ret);
|
||||
if(ret == HTTP_CLIENT_SUCCESS || ret == HTTP_CLIENT_EOS)
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(http_msg->err_fn != NULL)
|
||||
http_msg->err_fn(http_msg->pSession, ret);
|
||||
}
|
||||
if(http_msg->sendData != NULL)
|
||||
tls_mem_free(http_msg->sendData);
|
||||
if(http_msg->param.Uri)
|
||||
tls_mem_free(http_msg->param.Uri);
|
||||
tls_mem_free(http_msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int http_client_task_init(void)
|
||||
{
|
||||
if(sys_mbox_new(&http_client_mbox, 32) != ERR_OK) {
|
||||
return WM_FAILED;
|
||||
}
|
||||
tls_os_task_create(NULL, "HTTPCLNT",
|
||||
http_client_rx,
|
||||
NULL,
|
||||
(void *)httpClientStk, /* task's stack start address */
|
||||
HTTP_CLIENT_STK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
|
||||
TLS_HTTP_CLIENT_TASK_PRIO,
|
||||
0);
|
||||
return WM_SUCCESS;
|
||||
}
|
||||
|
||||
int http_client_post(http_client_msg * msg)
|
||||
{
|
||||
int len;
|
||||
err_t err;
|
||||
http_client_msg * msg1 = tls_mem_alloc(sizeof(http_client_msg));
|
||||
if(!msg1)
|
||||
return HTTP_CLIENT_ERROR_NO_MEMORY;
|
||||
memset(msg1, 0, sizeof(http_client_msg));
|
||||
memcpy(msg1, msg, sizeof(http_client_msg));
|
||||
if(msg->dataLen > 0)
|
||||
{
|
||||
msg1->sendData = tls_mem_alloc(msg->dataLen);
|
||||
if(msg1->sendData == NULL)
|
||||
{
|
||||
tls_mem_free(msg1);
|
||||
return HTTP_CLIENT_ERROR_NO_MEMORY;
|
||||
}
|
||||
memcpy(msg1->sendData, msg->sendData, msg->dataLen);
|
||||
}
|
||||
else
|
||||
msg1->sendData = NULL;
|
||||
if(msg->param.Uri != NULL)
|
||||
{
|
||||
len = strlen(msg->param.Uri);
|
||||
msg1->param.Uri = tls_mem_alloc(len + 1);
|
||||
if(msg1->param.Uri == NULL)
|
||||
{
|
||||
if(msg1->sendData)
|
||||
tls_mem_free(msg1->sendData);
|
||||
tls_mem_free(msg1);
|
||||
return HTTP_CLIENT_ERROR_NO_MEMORY;
|
||||
}
|
||||
memset(msg1->param.Uri, 0, len + 1);
|
||||
memcpy(msg1->param.Uri,msg->param.Uri,len);
|
||||
}
|
||||
|
||||
// Open the HTTP request handle
|
||||
msg->pSession= HTTPClientOpenRequest(0);
|
||||
if(!msg->pSession)
|
||||
{
|
||||
if(msg1->sendData)
|
||||
tls_mem_free(msg1->sendData);
|
||||
if(msg1->param.Uri)
|
||||
tls_mem_free(msg1->param.Uri);
|
||||
tls_mem_free(msg1);
|
||||
return HTTP_CLIENT_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
msg1->pSession = msg->pSession;
|
||||
err = sys_mbox_trypost(&http_client_mbox, msg1);
|
||||
//printf("post err=%d\n", err);
|
||||
if(err != ERR_OK)
|
||||
{
|
||||
HTTPClientCloseRequest(&msg->pSession);
|
||||
if(msg1->sendData)
|
||||
tls_mem_free(msg1->sendData);
|
||||
if(msg1->param.Uri)
|
||||
tls_mem_free(msg1->param.Uri);
|
||||
tls_mem_free(msg1);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
#endif //TLS_CONFIG_HTTP_CLIENT_TASK
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# THE VERSION NUMBER
|
||||
SET(CMAKE_SYSTEM_NAME Generic)
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 3.10)
|
||||
PROJECT(WMLWIP)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
|
||||
# ENABLE ASM
|
||||
ENABLE_LANGUAGE(ASM)
|
||||
|
||||
SET(CMAKE_STATIC_LIBRARY_PREFIX)
|
||||
SET(CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX)
|
||||
SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX)
|
||||
|
||||
# C FLAGS
|
||||
SET(CMAKE_C_FLAGS " -mthumb --function-sections --data-sections -mcpu=cortex-m3 -std=gnu99 -mabi=aapcs -march=armv7-m -fno-builtin ")
|
||||
STRING(APPEND CMAKE_C_FLAGS "-DGCC_COMPILE=1 -DWOLFSSL_USER_SETTINGS -D_IN_ADDR_T_DECLARED -D__MACHINE_ENDIAN_H__ -D_TIMEVAL_DEFINED -D__INSIDE_CYGWIN_NET__ ")
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -gdwarf-2 -Wall -DDEBUG ")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-Os -Wall")
|
||||
|
||||
|
||||
# DEBUG ASM FLAGS
|
||||
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O0 -g3 -gdwarf-2 -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin -DDEBUG ")
|
||||
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -Os -Wall -mthumb-interwork -mthumb -std=gnu99 -mcpu=cortex-m3 -march=armv7-m -mabi=aapcs -fno-builtin ")
|
||||
|
||||
# Library sources
|
||||
SET(LIBRARY_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/api2.0.3/tls_sockets.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/api2.0.3/tls_netconn.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/dns.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/def.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/init.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/mem.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/memp.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/netif.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/pbuf.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/raw.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/stats.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/sys.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/tcp.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/tcp_in.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/tcp_out.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/udp.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/inet_chksum.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ip.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/timeouts.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/alg.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/ip4_frag.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/ip4_addr.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/ip4.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/dhcp.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/etharp.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/igmp.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/icmp.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv4/autoip.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/ip6_frag.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/ip6_addr.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/ip6.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/dhcp6.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/ethip6.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/icmp6.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/inet6.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/mld6.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/core/ipv6/nd6.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/sys_arch.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/netif/ethernetif.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/netif/ethernet.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/netif/wm_ethernet.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/tcpip.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/api_lib.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/api_msg.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/err.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/netbuf.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/netdb.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/netifapi.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/api/sockets.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lwip2.0.3/apps/mdns/mdns.c"
|
||||
)
|
||||
|
||||
function(ADD_LIB_TARGET LIBTARGET)
|
||||
add_library(${LIBTARGET} OBJECT ${LIBRARY_SOURCES})
|
||||
# ADD_CUSTOM_COMMAND(TARGET ${LIBTARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXECUTABLE_OUTPUT_PATH}/${LIBTARGET} ${CMAKE_CURRENT_SOURCE_DIR}/../../Lib/GNU/${LIBTARGET})
|
||||
endfunction()
|
||||
|
||||
ADD_LIB_TARGET(wmlwip.a)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,93 @@
|
||||
/**************************************************************************
|
||||
* File Name : tls_netconn.h
|
||||
* Author :
|
||||
* Version :
|
||||
* Date :
|
||||
* Description :
|
||||
*
|
||||
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TLS_NETCONN_H
|
||||
#define TLS_NETCONN_H
|
||||
|
||||
#include "tls_common.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "list.h"
|
||||
#include "lwip/err.h"
|
||||
#include "wm_socket.h"
|
||||
#include "arch/sys_arch.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "wm_netif.h"
|
||||
|
||||
#define TLS_NETCONN_TCP 0
|
||||
#define TLS_NETCONN_UDP 1
|
||||
|
||||
#define RAW_SOCKET_USE_CUSTOM_PBUF LWIP_SUPPORT_CUSTOM_PBUF
|
||||
|
||||
#define CONN_SEM_NOT_FREE 1
|
||||
|
||||
/** A netconn descriptor */
|
||||
struct tls_netconn {
|
||||
struct dl_list list;
|
||||
struct tls_socket_desc *skd;
|
||||
u8 skt_num;
|
||||
bool used;
|
||||
|
||||
/* client or server mode */
|
||||
bool client;
|
||||
ip_addr_t addr;
|
||||
u16 port;
|
||||
u16 localport;
|
||||
u16 proto;
|
||||
/* the lwIP internal protocol control block */
|
||||
union {
|
||||
struct ip_pcb *ip;
|
||||
struct tcp_pcb *tcp;
|
||||
struct udp_pcb *udp;
|
||||
struct raw_pcb *raw;
|
||||
} pcb;
|
||||
bool write_state;
|
||||
u16 write_offset;
|
||||
struct tls_net_msg *current_msg;
|
||||
u8 tcp_connect_cnt;
|
||||
u8 state;
|
||||
err_t last_err;
|
||||
#if !CONN_SEM_NOT_FREE
|
||||
sys_sem_t op_completed;
|
||||
#endif
|
||||
u32 idle_time;
|
||||
|
||||
};
|
||||
|
||||
struct tls_net_msg {
|
||||
struct dl_list list;
|
||||
//struct tls_netconn *conn;
|
||||
void *dataptr;
|
||||
struct pbuf *p;
|
||||
ip_addr_t addr;
|
||||
u16 port;
|
||||
u32 len;
|
||||
u32 write_offset;
|
||||
err_t err;
|
||||
int skt_no;
|
||||
};
|
||||
#if (RAW_SOCKET_USE_CUSTOM_PBUF)
|
||||
struct raw_sk_pbuf_custom{
|
||||
/** 'base class' */
|
||||
struct pbuf_custom pc;
|
||||
/** pointer to the original pbuf that is referenced */
|
||||
struct pbuf *original;
|
||||
/*custom pbuf free function used*/
|
||||
void *conn;
|
||||
void *pcb;
|
||||
};
|
||||
#endif
|
||||
|
||||
int tls_net_init(void);
|
||||
struct tls_netconn * tls_net_get_socket(u8 socket);
|
||||
|
||||
#endif /* end of TLS_NETCONN_H */
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
extern struct hostent* lwip_gethostbyname(const char *name);
|
||||
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)
|
||||
{
|
||||
return lwip_bind(s, name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
shutdown(int s, int how)
|
||||
{
|
||||
return lwip_shutdown(s, how);
|
||||
}
|
||||
|
||||
int
|
||||
closesocket(int s)
|
||||
{
|
||||
return lwip_close(s);
|
||||
}
|
||||
|
||||
int
|
||||
connect(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
return lwip_connect(s, name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
getsockname(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
return lwip_getsockname(s, name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
getpeername(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
return lwip_getpeername(s, name, namelen);
|
||||
}
|
||||
|
||||
int
|
||||
setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
|
||||
{
|
||||
return lwip_setsockopt(s, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int
|
||||
getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
{
|
||||
return lwip_getsockopt(s, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int
|
||||
listen(int s, int backlog)
|
||||
{
|
||||
return lwip_listen(s, backlog);
|
||||
}
|
||||
|
||||
int
|
||||
recv(int s, void *mem, size_t len, int flags)
|
||||
{
|
||||
return lwip_recv(s, mem, len, flags);
|
||||
}
|
||||
|
||||
int
|
||||
recvfrom(int s, void *mem, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
return lwip_recvfrom(s, mem, len, flags, from, fromlen);
|
||||
}
|
||||
|
||||
int
|
||||
send(int s, const void *data, size_t size, int flags)
|
||||
{
|
||||
return lwip_send(s, data, size, flags);
|
||||
}
|
||||
|
||||
int
|
||||
sendto(int s, const void *data, size_t size, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
return lwip_sendto(s, data, size, flags, to, tolen);
|
||||
}
|
||||
|
||||
int
|
||||
socket(int domain, int type, int protocol)
|
||||
{
|
||||
return lwip_socket(domain, type, protocol);
|
||||
}
|
||||
|
||||
int
|
||||
select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
|
||||
}
|
||||
|
||||
int
|
||||
ioctlsocket(int s, long cmd, void *argp)
|
||||
{
|
||||
return lwip_ioctl(s, cmd, argp);
|
||||
}
|
||||
|
||||
int
|
||||
fcntl(int s, int cmd, int val)
|
||||
{
|
||||
return lwip_fcntl(s, cmd, val);
|
||||
}
|
||||
struct hostent* gethostbyname(const char *name){
|
||||
return lwip_gethostbyname(name);
|
||||
}
|
||||
|
||||
#endif /* LWIP_SOCKET */
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef WM_LWIP_COMPILE_FILES
|
||||
#define WM_LWIP_COMPILE_FILES
|
||||
#include "wm_config.h"
|
||||
#include "../Src/Network/api2.0.3/tls_sockets.c"
|
||||
#include "../Src/Network/api2.0.3/tls_netconn.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/def.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/dns.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/init.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/mem.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/memp.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/netif.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/pbuf.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/raw.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/stats.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/sys.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/tcp.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/tcp_in.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/tcp_out.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/udp.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/inet_chksum.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ip.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/timeouts.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/alg.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/ip4_frag.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/ip4_addr.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/ip4.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/dhcp.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/etharp.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/igmp.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/icmp.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv4/autoip.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/ip6_frag.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/ip6_addr.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/ip6.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/dhcp6.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/ethip6.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/icmp6.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/inet6.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/mld6.c"
|
||||
#include "../Src/Network/lwip2.0.3/core/ipv6/nd6.c"
|
||||
#include "../Src/Network/lwip2.0.3/sys_arch.c"
|
||||
#include "../Src/Network/lwip2.0.3/netif/ethernetif.c"
|
||||
#include "../Src/Network/lwip2.0.3/netif/ethernet.c"
|
||||
#include "../Src/Network/lwip2.0.3/netif/wm_ethernet.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/tcpip.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/api_lib.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/api_msg.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/err.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/netbuf.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/netdb.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/netifapi.c"
|
||||
#include "../Src/Network/lwip2.0.3/api/sockets.c"
|
||||
|
||||
#endif // WM_LWIP_COMPILE_FILES
|
||||
@@ -0,0 +1,15 @@
|
||||
api/ - The code for the high-level wrapper API. Not needed if
|
||||
you use the lowel-level call-back/raw API.
|
||||
|
||||
apps/ - Higher layer applications that are specifically programmed
|
||||
with the lwIP low-level raw API.
|
||||
|
||||
core/ - The core of the TPC/IP stack; protocol implementations,
|
||||
memory and buffer management, and the low-level raw API.
|
||||
|
||||
include/ - lwIP include files.
|
||||
|
||||
netif/ - Generic network interface device drivers are kept here.
|
||||
|
||||
For more information on the various subdirectories, check the FILES
|
||||
file in each directory.
|
||||
@@ -0,0 +1,181 @@
|
||||
#
|
||||
# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
# SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
#
|
||||
# This file is part of the lwIP TCP/IP stack.
|
||||
#
|
||||
# Author: Adam Dunkels <adam@sics.se>
|
||||
#
|
||||
|
||||
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
|
||||
COREFILES=$(LWIPDIR)/core/init.c \
|
||||
$(LWIPDIR)/core/def.c \
|
||||
$(LWIPDIR)/core/dns.c \
|
||||
$(LWIPDIR)/core/inet_chksum.c \
|
||||
$(LWIPDIR)/core/ip.c \
|
||||
$(LWIPDIR)/core/mem.c \
|
||||
$(LWIPDIR)/core/memp.c \
|
||||
$(LWIPDIR)/core/netif.c \
|
||||
$(LWIPDIR)/core/pbuf.c \
|
||||
$(LWIPDIR)/core/raw.c \
|
||||
$(LWIPDIR)/core/stats.c \
|
||||
$(LWIPDIR)/core/sys.c \
|
||||
$(LWIPDIR)/core/tcp.c \
|
||||
$(LWIPDIR)/core/tcp_in.c \
|
||||
$(LWIPDIR)/core/tcp_out.c \
|
||||
$(LWIPDIR)/core/timeouts.c \
|
||||
$(LWIPDIR)/core/udp.c
|
||||
|
||||
CORE4FILES=$(LWIPDIR)/core/ipv4/autoip.c \
|
||||
$(LWIPDIR)/core/ipv4/dhcp.c \
|
||||
$(LWIPDIR)/core/ipv4/etharp.c \
|
||||
$(LWIPDIR)/core/ipv4/icmp.c \
|
||||
$(LWIPDIR)/core/ipv4/igmp.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_frag.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_addr.c
|
||||
|
||||
CORE6FILES=$(LWIPDIR)/core/ipv6/dhcp6.c \
|
||||
$(LWIPDIR)/core/ipv6/ethip6.c \
|
||||
$(LWIPDIR)/core/ipv6/icmp6.c \
|
||||
$(LWIPDIR)/core/ipv6/inet6.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6_addr.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6_frag.c \
|
||||
$(LWIPDIR)/core/ipv6/mld6.c \
|
||||
$(LWIPDIR)/core/ipv6/nd6.c
|
||||
|
||||
# APIFILES: The files which implement the sequential and socket APIs.
|
||||
APIFILES=$(LWIPDIR)/api/api_lib.c \
|
||||
$(LWIPDIR)/api/api_msg.c \
|
||||
$(LWIPDIR)/api/err.c \
|
||||
$(LWIPDIR)/api/netbuf.c \
|
||||
$(LWIPDIR)/api/netdb.c \
|
||||
$(LWIPDIR)/api/netifapi.c \
|
||||
$(LWIPDIR)/api/sockets.c \
|
||||
$(LWIPDIR)/api/tcpip.c
|
||||
|
||||
# NETIFFILES: Files implementing various generic network interface functions
|
||||
NETIFFILES=$(LWIPDIR)/netif/ethernet.c \
|
||||
$(LWIPDIR)/netif/slipif.c
|
||||
|
||||
# SIXLOWPAN: 6LoWPAN
|
||||
SIXLOWPAN=$(LWIPDIR)/netif/lowpan6.c \
|
||||
|
||||
# PPPFILES: PPP
|
||||
PPPFILES=$(LWIPDIR)/netif/ppp/auth.c \
|
||||
$(LWIPDIR)/netif/ppp/ccp.c \
|
||||
$(LWIPDIR)/netif/ppp/chap-md5.c \
|
||||
$(LWIPDIR)/netif/ppp/chap_ms.c \
|
||||
$(LWIPDIR)/netif/ppp/chap-new.c \
|
||||
$(LWIPDIR)/netif/ppp/demand.c \
|
||||
$(LWIPDIR)/netif/ppp/eap.c \
|
||||
$(LWIPDIR)/netif/ppp/ecp.c \
|
||||
$(LWIPDIR)/netif/ppp/eui64.c \
|
||||
$(LWIPDIR)/netif/ppp/fsm.c \
|
||||
$(LWIPDIR)/netif/ppp/ipcp.c \
|
||||
$(LWIPDIR)/netif/ppp/ipv6cp.c \
|
||||
$(LWIPDIR)/netif/ppp/lcp.c \
|
||||
$(LWIPDIR)/netif/ppp/magic.c \
|
||||
$(LWIPDIR)/netif/ppp/mppe.c \
|
||||
$(LWIPDIR)/netif/ppp/multilink.c \
|
||||
$(LWIPDIR)/netif/ppp/ppp.c \
|
||||
$(LWIPDIR)/netif/ppp/pppapi.c \
|
||||
$(LWIPDIR)/netif/ppp/pppcrypt.c \
|
||||
$(LWIPDIR)/netif/ppp/pppoe.c \
|
||||
$(LWIPDIR)/netif/ppp/pppol2tp.c \
|
||||
$(LWIPDIR)/netif/ppp/pppos.c \
|
||||
$(LWIPDIR)/netif/ppp/upap.c \
|
||||
$(LWIPDIR)/netif/ppp/utils.c \
|
||||
$(LWIPDIR)/netif/ppp/vj.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/arc4.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/des.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/md4.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/md5.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/sha1.c
|
||||
|
||||
# LWIPNOAPPSFILES: All LWIP files without apps
|
||||
LWIPNOAPPSFILES=$(COREFILES) \
|
||||
$(CORE4FILES) \
|
||||
$(CORE6FILES) \
|
||||
$(APIFILES) \
|
||||
$(NETIFFILES) \
|
||||
$(PPPFILES) \
|
||||
$(SIXLOWPAN)
|
||||
|
||||
# SNMPFILES: SNMPv2c agent
|
||||
SNMPFILES=$(LWIPDIR)/apps/snmp/snmp_asn1.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_core.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_icmp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_interfaces.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_ip.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_snmp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_system.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_tcp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_udp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_msg.c \
|
||||
$(LWIPDIR)/apps/snmp/snmpv3.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_netconn.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_pbuf_stream.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_raw.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_scalar.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_table.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_threadsync.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_traps.c \
|
||||
$(LWIPDIR)/apps/snmp/snmpv3_mbedtls.c \
|
||||
$(LWIPDIR)/apps/snmp/snmpv3_dummy.c
|
||||
|
||||
# HTTPDFILES: HTTP server
|
||||
HTTPDFILES=$(LWIPDIR)/apps/httpd/fs.c \
|
||||
$(LWIPDIR)/apps/httpd/httpd.c
|
||||
|
||||
# LWIPERFFILES: IPERF server
|
||||
LWIPERFFILES=$(LWIPDIR)/apps/lwiperf/lwiperf.c
|
||||
|
||||
# SNTPFILES: SNTP client
|
||||
SNTPFILES=$(LWIPDIR)/apps/sntp/sntp.c
|
||||
|
||||
# MDNSFILES: MDNS responder
|
||||
MDNSFILES=$(LWIPDIR)/apps/mdns/mdns.c
|
||||
|
||||
# NETBIOSNSFILES: NetBIOS name server
|
||||
NETBIOSNSFILES=$(LWIPDIR)/apps/netbiosns/netbiosns.c
|
||||
|
||||
# TFTPFILES: TFTP server files
|
||||
TFTPFILES=$(LWIPDIR)/apps/tftp/tftp_server.c
|
||||
|
||||
# MQTTFILES: MQTT client files
|
||||
MQTTFILES=$(LWIPDIR)/apps/mqtt/mqtt.c
|
||||
|
||||
# LWIPAPPFILES: All LWIP APPs
|
||||
LWIPAPPFILES=$(SNMPFILES) \
|
||||
$(HTTPDFILES) \
|
||||
$(LWIPERFFILES) \
|
||||
$(SNTPFILES) \
|
||||
$(MDNSFILES) \
|
||||
$(NETBIOSNSFILES) \
|
||||
$(TFTPFILES) \
|
||||
$(MQTTFILES)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file
|
||||
* Error Management module
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include "lwip/errno.h"
|
||||
|
||||
#if !NO_SYS
|
||||
/** Table to quickly map an lwIP error (err_t) to a socket error
|
||||
* by using -err as an index */
|
||||
static const int err_to_errno_table[] = {
|
||||
0, /* ERR_OK 0 No error, everything OK. */
|
||||
ENOMEM, /* ERR_MEM -1 Out of memory error. */
|
||||
ENOBUFS, /* ERR_BUF -2 Buffer error. */
|
||||
EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
|
||||
EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
|
||||
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
|
||||
EINVAL, /* ERR_VAL -6 Illegal value. */
|
||||
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
|
||||
EADDRINUSE, /* ERR_USE -8 Address in use. */
|
||||
EALREADY, /* ERR_ALREADY -9 Already connecting. */
|
||||
EISCONN, /* ERR_ISCONN -10 Conn already established.*/
|
||||
ENOTCONN, /* ERR_CONN -11 Not connected. */
|
||||
-1, /* ERR_IF -12 Low-level netif error */
|
||||
ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */
|
||||
ECONNRESET, /* ERR_RST -14 Connection reset. */
|
||||
ENOTCONN, /* ERR_CLSD -15 Connection closed. */
|
||||
EIO /* ERR_ARG -16 Illegal argument. */
|
||||
};
|
||||
|
||||
int
|
||||
err_to_errno(err_t err)
|
||||
{
|
||||
if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_to_errno_table))) {
|
||||
return EIO;
|
||||
}
|
||||
return err_to_errno_table[-err];
|
||||
}
|
||||
#endif /* !NO_SYS */
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
|
||||
static const char *err_strerr[] = {
|
||||
"Ok.", /* ERR_OK 0 */
|
||||
"Out of memory error.", /* ERR_MEM -1 */
|
||||
"Buffer error.", /* ERR_BUF -2 */
|
||||
"Timeout.", /* ERR_TIMEOUT -3 */
|
||||
"Routing problem.", /* ERR_RTE -4 */
|
||||
"Operation in progress.", /* ERR_INPROGRESS -5 */
|
||||
"Illegal value.", /* ERR_VAL -6 */
|
||||
"Operation would block.", /* ERR_WOULDBLOCK -7 */
|
||||
"Address in use.", /* ERR_USE -8 */
|
||||
"Already connecting.", /* ERR_ALREADY -9 */
|
||||
"Already connected.", /* ERR_ISCONN -10 */
|
||||
"Not connected.", /* ERR_CONN -11 */
|
||||
"Low-level netif error.", /* ERR_IF -12 */
|
||||
"Connection aborted.", /* ERR_ABRT -13 */
|
||||
"Connection reset.", /* ERR_RST -14 */
|
||||
"Connection closed.", /* ERR_CLSD -15 */
|
||||
"Illegal argument." /* ERR_ARG -16 */
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert an lwip internal error to a string representation.
|
||||
*
|
||||
* @param err an lwip internal err_t
|
||||
* @return a string representation for err
|
||||
*/
|
||||
const char *
|
||||
lwip_strerr(err_t err)
|
||||
{
|
||||
if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_strerr))) {
|
||||
return "Unknown error.";
|
||||
}
|
||||
return err_strerr[-err];
|
||||
}
|
||||
|
||||
#endif /* LWIP_DEBUG */
|
||||
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
* @file
|
||||
* Network buffer management
|
||||
*
|
||||
* @defgroup netbuf Network buffers
|
||||
* @ingroup netconn
|
||||
* Network buffer descriptor for @ref netconn. Based on @ref pbuf internally
|
||||
* to avoid copying data around.\n
|
||||
* Buffers must not be shared accross multiple threads, all functions except
|
||||
* netbuf_new() and netbuf_delete() are not thread-safe.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/netbuf.h"
|
||||
#include "lwip/memp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Create (allocate) and initialize a new netbuf.
|
||||
* The netbuf doesn't yet contain a packet buffer!
|
||||
*
|
||||
* @return a pointer to a new netbuf
|
||||
* NULL on lack of memory
|
||||
*/
|
||||
struct
|
||||
netbuf *netbuf_new(void)
|
||||
{
|
||||
struct netbuf *buf;
|
||||
|
||||
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
|
||||
if (buf != NULL) {
|
||||
memset(buf, 0, sizeof(struct netbuf));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Deallocate a netbuf allocated by netbuf_new().
|
||||
*
|
||||
* @param buf pointer to a netbuf allocated by netbuf_new()
|
||||
*/
|
||||
void
|
||||
netbuf_delete(struct netbuf *buf)
|
||||
{
|
||||
if (buf != NULL) {
|
||||
if (buf->p != NULL) {
|
||||
pbuf_free(buf->p);
|
||||
buf->p = buf->ptr = NULL;
|
||||
}
|
||||
memp_free(MEMP_NETBUF, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Allocate memory for a packet buffer for a given netbuf.
|
||||
*
|
||||
* @param buf the netbuf for which to allocate a packet buffer
|
||||
* @param size the size of the packet buffer to allocate
|
||||
* @return pointer to the allocated memory
|
||||
* NULL if no memory could be allocated
|
||||
*/
|
||||
void *
|
||||
netbuf_alloc(struct netbuf *buf, u16_t size)
|
||||
{
|
||||
LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
|
||||
|
||||
/* Deallocate any previously allocated memory. */
|
||||
if (buf->p != NULL) {
|
||||
pbuf_free(buf->p);
|
||||
}
|
||||
buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
|
||||
if (buf->p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
LWIP_ASSERT("check that first pbuf can hold size",
|
||||
(buf->p->len >= size));
|
||||
buf->ptr = buf->p;
|
||||
return buf->p->payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Free the packet buffer included in a netbuf
|
||||
*
|
||||
* @param buf pointer to the netbuf which contains the packet buffer to free
|
||||
*/
|
||||
void
|
||||
netbuf_free(struct netbuf *buf)
|
||||
{
|
||||
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
|
||||
if (buf->p != NULL) {
|
||||
pbuf_free(buf->p);
|
||||
}
|
||||
buf->p = buf->ptr = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Let a netbuf reference existing (non-volatile) data.
|
||||
*
|
||||
* @param buf netbuf which should reference the data
|
||||
* @param dataptr pointer to the data to reference
|
||||
* @param size size of the data
|
||||
* @return ERR_OK if data is referenced
|
||||
* ERR_MEM if data couldn't be referenced due to lack of memory
|
||||
*/
|
||||
err_t
|
||||
netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size)
|
||||
{
|
||||
LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;);
|
||||
if (buf->p != NULL) {
|
||||
pbuf_free(buf->p);
|
||||
}
|
||||
buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
|
||||
if (buf->p == NULL) {
|
||||
buf->ptr = NULL;
|
||||
return ERR_MEM;
|
||||
}
|
||||
((struct pbuf_rom*)buf->p)->payload = dataptr;
|
||||
buf->p->len = buf->p->tot_len = size;
|
||||
buf->ptr = buf->p;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Chain one netbuf to another (@see pbuf_chain)
|
||||
*
|
||||
* @param head the first netbuf
|
||||
* @param tail netbuf to chain after head, freed by this function, may not be reference after returning
|
||||
*/
|
||||
void
|
||||
netbuf_chain(struct netbuf *head, struct netbuf *tail)
|
||||
{
|
||||
LWIP_ERROR("netbuf_chain: invalid head", (head != NULL), return;);
|
||||
LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;);
|
||||
pbuf_cat(head->p, tail->p);
|
||||
head->ptr = head->p;
|
||||
memp_free(MEMP_NETBUF, tail);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Get the data pointer and length of the data inside a netbuf.
|
||||
*
|
||||
* @param buf netbuf to get the data from
|
||||
* @param dataptr pointer to a void pointer where to store the data pointer
|
||||
* @param len pointer to an u16_t where the length of the data is stored
|
||||
* @return ERR_OK if the information was retrieved,
|
||||
* ERR_BUF on error.
|
||||
*/
|
||||
err_t
|
||||
netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
|
||||
{
|
||||
LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;);
|
||||
|
||||
if (buf->ptr == NULL) {
|
||||
return ERR_BUF;
|
||||
}
|
||||
*dataptr = buf->ptr->payload;
|
||||
*len = buf->ptr->len;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Move the current data pointer of a packet buffer contained in a netbuf
|
||||
* to the next part.
|
||||
* The packet buffer itself is not modified.
|
||||
*
|
||||
* @param buf the netbuf to modify
|
||||
* @return -1 if there is no next part
|
||||
* 1 if moved to the next part but now there is no next part
|
||||
* 0 if moved to the next part and there are still more parts
|
||||
*/
|
||||
s8_t
|
||||
netbuf_next(struct netbuf *buf)
|
||||
{
|
||||
LWIP_ERROR("netbuf_next: invalid buf", (buf != NULL), return -1;);
|
||||
if (buf->ptr->next == NULL) {
|
||||
return -1;
|
||||
}
|
||||
buf->ptr = buf->ptr->next;
|
||||
if (buf->ptr->next == NULL) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbuf
|
||||
* Move the current data pointer of a packet buffer contained in a netbuf
|
||||
* to the beginning of the packet.
|
||||
* The packet buffer itself is not modified.
|
||||
*
|
||||
* @param buf the netbuf to modify
|
||||
*/
|
||||
void
|
||||
netbuf_first(struct netbuf *buf)
|
||||
{
|
||||
LWIP_ERROR("netbuf_first: invalid buf", (buf != NULL), return;);
|
||||
buf->ptr = buf->p;
|
||||
}
|
||||
|
||||
#endif /* LWIP_NETCONN */
|
||||
@@ -0,0 +1,413 @@
|
||||
/**
|
||||
* @file
|
||||
* API functions for name resolving
|
||||
*
|
||||
* @defgroup netdbapi NETDB API
|
||||
* @ingroup socket
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Simon Goldschmidt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
#if LWIP_DNS && LWIP_SOCKET
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/dns.h"
|
||||
|
||||
#include <string.h> /* memset */
|
||||
#include <stdlib.h> /* atoi */
|
||||
|
||||
/** helper struct for gethostbyname_r to access the char* buffer */
|
||||
struct gethostbyname_r_helper {
|
||||
ip_addr_t *addr_list[2];
|
||||
ip_addr_t addr;
|
||||
char *aliases;
|
||||
};
|
||||
|
||||
/** h_errno is exported in netdb.h for access by applications. */
|
||||
#if LWIP_DNS_API_DECLARE_H_ERRNO
|
||||
int h_errno;
|
||||
#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
|
||||
|
||||
/** define "hostent" variables storage: 0 if we use a static (but unprotected)
|
||||
* set of variables for lwip_gethostbyname, 1 if we use a local storage */
|
||||
#ifndef LWIP_DNS_API_HOSTENT_STORAGE
|
||||
#define LWIP_DNS_API_HOSTENT_STORAGE 0
|
||||
#endif
|
||||
|
||||
/** define "hostent" variables storage */
|
||||
#if LWIP_DNS_API_HOSTENT_STORAGE
|
||||
#define HOSTENT_STORAGE
|
||||
#else
|
||||
#define HOSTENT_STORAGE static
|
||||
#endif /* LWIP_DNS_API_STATIC_HOSTENT */
|
||||
|
||||
/**
|
||||
* Returns an entry containing addresses of address family AF_INET
|
||||
* for the host with name name.
|
||||
* Due to dns_gethostbyname limitations, only one address is returned.
|
||||
*
|
||||
* @param name the hostname to resolve
|
||||
* @return an entry containing addresses of address family AF_INET
|
||||
* for the host with name name
|
||||
*/
|
||||
struct hostent*
|
||||
lwip_gethostbyname(const char *name)
|
||||
{
|
||||
err_t err;
|
||||
ip_addr_t addr;
|
||||
|
||||
/* buffer variables for lwip_gethostbyname() */
|
||||
HOSTENT_STORAGE struct hostent s_hostent;
|
||||
HOSTENT_STORAGE char *s_aliases;
|
||||
HOSTENT_STORAGE ip_addr_t s_hostent_addr;
|
||||
HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2];
|
||||
HOSTENT_STORAGE char s_hostname[DNS_MAX_NAME_LENGTH + 1];
|
||||
|
||||
/* query host IP address */
|
||||
err = netconn_gethostbyname(name, &addr);
|
||||
if (err != ERR_OK) {
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fill hostent */
|
||||
s_hostent_addr = addr;
|
||||
s_phostent_addr[0] = &s_hostent_addr;
|
||||
s_phostent_addr[1] = NULL;
|
||||
strncpy(s_hostname, name, DNS_MAX_NAME_LENGTH);
|
||||
s_hostname[DNS_MAX_NAME_LENGTH] = 0;
|
||||
s_hostent.h_name = s_hostname;
|
||||
s_aliases = NULL;
|
||||
s_hostent.h_aliases = &s_aliases;
|
||||
s_hostent.h_addrtype = AF_INET;
|
||||
s_hostent.h_length = sizeof(ip_addr_t);
|
||||
s_hostent.h_addr_list = (char**)&s_phostent_addr;
|
||||
|
||||
#if DNS_DEBUG
|
||||
/* dump hostent */
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name));
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", (void*)s_hostent.h_aliases));
|
||||
/* h_aliases are always empty */
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype));
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length));
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", (void*)s_hostent.h_addr_list));
|
||||
if (s_hostent.h_addr_list != NULL) {
|
||||
u8_t idx;
|
||||
for (idx=0; s_hostent.h_addr_list[idx]; idx++) {
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx])));
|
||||
}
|
||||
}
|
||||
#endif /* DNS_DEBUG */
|
||||
|
||||
#if LWIP_DNS_API_HOSTENT_STORAGE
|
||||
/* this function should return the "per-thread" hostent after copy from s_hostent */
|
||||
return sys_thread_hostent(&s_hostent);
|
||||
#else
|
||||
return &s_hostent;
|
||||
#endif /* LWIP_DNS_API_HOSTENT_STORAGE */
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread-safe variant of lwip_gethostbyname: instead of using a static
|
||||
* buffer, this function takes buffer and errno pointers as arguments
|
||||
* and uses these for the result.
|
||||
*
|
||||
* @param name the hostname to resolve
|
||||
* @param ret pre-allocated struct where to store the result
|
||||
* @param buf pre-allocated buffer where to store additional data
|
||||
* @param buflen the size of buf
|
||||
* @param result pointer to a hostent pointer that is set to ret on success
|
||||
* and set to zero on error
|
||||
* @param h_errnop pointer to an int where to store errors (instead of modifying
|
||||
* the global h_errno)
|
||||
* @return 0 on success, non-zero on error, additional error information
|
||||
* is stored in *h_errnop instead of h_errno to be thread-safe
|
||||
*/
|
||||
int
|
||||
lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
||||
size_t buflen, struct hostent **result, int *h_errnop)
|
||||
{
|
||||
err_t err;
|
||||
struct gethostbyname_r_helper *h;
|
||||
char *hostname;
|
||||
size_t namelen;
|
||||
int lh_errno;
|
||||
|
||||
if (h_errnop == NULL) {
|
||||
/* ensure h_errnop is never NULL */
|
||||
h_errnop = &lh_errno;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
/* not all arguments given */
|
||||
*h_errnop = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
/* first thing to do: set *result to nothing */
|
||||
*result = NULL;
|
||||
if ((name == NULL) || (ret == NULL) || (buf == NULL)) {
|
||||
/* not all arguments given */
|
||||
*h_errnop = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
namelen = strlen(name);
|
||||
if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
|
||||
/* buf can't hold the data needed + a copy of name */
|
||||
*h_errnop = ERANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
|
||||
hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
|
||||
|
||||
/* query host IP address */
|
||||
err = netconn_gethostbyname(name, &h->addr);
|
||||
if (err != ERR_OK) {
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy the hostname into buf */
|
||||
MEMCPY(hostname, name, namelen);
|
||||
hostname[namelen] = 0;
|
||||
|
||||
/* fill hostent */
|
||||
h->addr_list[0] = &h->addr;
|
||||
h->addr_list[1] = NULL;
|
||||
h->aliases = NULL;
|
||||
ret->h_name = hostname;
|
||||
ret->h_aliases = &h->aliases;
|
||||
ret->h_addrtype = AF_INET;
|
||||
ret->h_length = sizeof(ip_addr_t);
|
||||
ret->h_addr_list = (char**)&h->addr_list;
|
||||
|
||||
/* set result != NULL */
|
||||
*result = ret;
|
||||
|
||||
/* return success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees one or more addrinfo structures returned by getaddrinfo(), along with
|
||||
* any additional storage associated with those structures. If the ai_next field
|
||||
* of the structure is not null, the entire list of structures is freed.
|
||||
*
|
||||
* @param ai struct addrinfo to free
|
||||
*/
|
||||
void
|
||||
lwip_freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
struct addrinfo *next;
|
||||
|
||||
while (ai != NULL) {
|
||||
next = ai->ai_next;
|
||||
memp_free(MEMP_NETDB, ai);
|
||||
ai = next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the name of a service location (for example, a host name) and/or
|
||||
* a service name and returns a set of socket addresses and associated
|
||||
* information to be used in creating a socket with which to address the
|
||||
* specified service.
|
||||
* Memory for the result is allocated internally and must be freed by calling
|
||||
* lwip_freeaddrinfo()!
|
||||
*
|
||||
* Due to a limitation in dns_gethostbyname, only the first address of a
|
||||
* host is returned.
|
||||
* Also, service names are not supported (only port numbers)!
|
||||
*
|
||||
* @param nodename descriptive name or address string of the host
|
||||
* (may be NULL -> local address)
|
||||
* @param servname port number as string of NULL
|
||||
* @param hints structure containing input values that set socktype and protocol
|
||||
* @param res pointer to a pointer where to store the result (set to NULL on failure)
|
||||
* @return 0 on success, non-zero on failure
|
||||
*
|
||||
* @todo: implement AI_V4MAPPED, AI_ADDRCONFIG
|
||||
*/
|
||||
int
|
||||
lwip_getaddrinfo(const char *nodename, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
err_t err;
|
||||
ip_addr_t addr;
|
||||
struct addrinfo *ai;
|
||||
struct sockaddr_storage *sa = NULL;
|
||||
int port_nr = 0;
|
||||
size_t total_size;
|
||||
size_t namelen = 0;
|
||||
int ai_family;
|
||||
|
||||
if (res == NULL) {
|
||||
return EAI_FAIL;
|
||||
}
|
||||
*res = NULL;
|
||||
if ((nodename == NULL) && (servname == NULL)) {
|
||||
return EAI_NONAME;
|
||||
}
|
||||
|
||||
if (hints != NULL) {
|
||||
ai_family = hints->ai_family;
|
||||
if ((ai_family != AF_UNSPEC)
|
||||
#if LWIP_IPV4
|
||||
&& (ai_family != AF_INET)
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV6
|
||||
&& (ai_family != AF_INET6)
|
||||
#endif /* LWIP_IPV6 */
|
||||
) {
|
||||
return EAI_FAMILY;
|
||||
}
|
||||
} else {
|
||||
ai_family = AF_UNSPEC;
|
||||
}
|
||||
|
||||
if (servname != NULL) {
|
||||
/* service name specified: convert to port number
|
||||
* @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */
|
||||
port_nr = atoi(servname);
|
||||
if ((port_nr <= 0) || (port_nr > 0xffff)) {
|
||||
return EAI_SERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodename != NULL) {
|
||||
/* service location specified, try to resolve */
|
||||
if ((hints != NULL) && (hints->ai_flags & AI_NUMERICHOST)) {
|
||||
/* no DNS lookup, just parse for an address string */
|
||||
if (!ipaddr_aton(nodename, &addr)) {
|
||||
return EAI_NONAME;
|
||||
}
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) ||
|
||||
(IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) {
|
||||
return EAI_NONAME;
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
} else {
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* AF_UNSPEC: prefer IPv4 */
|
||||
u8_t type = NETCONN_DNS_IPV4_IPV6;
|
||||
if (ai_family == AF_INET) {
|
||||
type = NETCONN_DNS_IPV4;
|
||||
} else if (ai_family == AF_INET6) {
|
||||
type = NETCONN_DNS_IPV6;
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
err = netconn_gethostbyname_addrtype(nodename, &addr, type);
|
||||
if (err != ERR_OK) {
|
||||
return EAI_FAIL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* service location specified, use loopback address */
|
||||
if ((hints != NULL) && (hints->ai_flags & AI_PASSIVE)) {
|
||||
ip_addr_set_any(ai_family == AF_INET6, &addr);
|
||||
} else {
|
||||
ip_addr_set_loopback(ai_family == AF_INET6, &addr);
|
||||
}
|
||||
}
|
||||
|
||||
total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage);
|
||||
if (nodename != NULL) {
|
||||
namelen = strlen(nodename);
|
||||
if (namelen > DNS_MAX_NAME_LENGTH) {
|
||||
/* invalid name length */
|
||||
return EAI_FAIL;
|
||||
}
|
||||
LWIP_ASSERT("namelen is too long", total_size + namelen + 1 > total_size);
|
||||
total_size += namelen + 1;
|
||||
}
|
||||
/* If this fails, please report to lwip-devel! :-) */
|
||||
LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
|
||||
total_size <= NETDB_ELEM_SIZE);
|
||||
ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
|
||||
if (ai == NULL) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
memset(ai, 0, total_size);
|
||||
/* cast through void* to get rid of alignment warnings */
|
||||
sa = (struct sockaddr_storage *)(void*)((u8_t*)ai + sizeof(struct addrinfo));
|
||||
if (IP_IS_V6_VAL(addr)) {
|
||||
#if LWIP_IPV6
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)sa;
|
||||
/* set up sockaddr */
|
||||
inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr));
|
||||
sa6->sin6_family = AF_INET6;
|
||||
sa6->sin6_len = sizeof(struct sockaddr_in6);
|
||||
sa6->sin6_port = lwip_htons((u16_t)port_nr);
|
||||
ai->ai_family = AF_INET6;
|
||||
#endif /* LWIP_IPV6 */
|
||||
} else {
|
||||
#if LWIP_IPV4
|
||||
struct sockaddr_in *sa4 = (struct sockaddr_in*)sa;
|
||||
/* set up sockaddr */
|
||||
inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr));
|
||||
sa4->sin_family = AF_INET;
|
||||
sa4->sin_len = sizeof(struct sockaddr_in);
|
||||
sa4->sin_port = lwip_htons((u16_t)port_nr);
|
||||
ai->ai_family = AF_INET;
|
||||
#endif /* LWIP_IPV4 */
|
||||
}
|
||||
|
||||
/* set up addrinfo */
|
||||
if (hints != NULL) {
|
||||
/* copy socktype & protocol from hints if specified */
|
||||
ai->ai_socktype = hints->ai_socktype;
|
||||
ai->ai_protocol = hints->ai_protocol;
|
||||
}
|
||||
if (nodename != NULL) {
|
||||
/* copy nodename to canonname if specified */
|
||||
ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
|
||||
MEMCPY(ai->ai_canonname, nodename, namelen);
|
||||
ai->ai_canonname[namelen] = 0;
|
||||
}
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_storage);
|
||||
ai->ai_addr = (struct sockaddr*)sa;
|
||||
|
||||
*res = ai;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LWIP_DNS && LWIP_SOCKET */
|
||||
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* @file
|
||||
* Network Interface Sequential API module
|
||||
*
|
||||
* @defgroup netifapi NETIF API
|
||||
* @ingroup sequential_api
|
||||
* Thread-safe functions to be called from non-TCPIP threads
|
||||
*
|
||||
* @defgroup netifapi_netif NETIF related
|
||||
* @ingroup netifapi
|
||||
* To be called from non-TCPIP threads
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/netifapi.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
|
||||
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
|
||||
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
|
||||
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
|
||||
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
|
||||
|
||||
/**
|
||||
* Call netif_add() inside the tcpip_thread context.
|
||||
*/
|
||||
static err_t
|
||||
netifapi_do_netif_add(struct tcpip_api_call_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;
|
||||
|
||||
if (!netif_add( msg->netif,
|
||||
#if LWIP_IPV4
|
||||
API_EXPR_REF(msg->msg.add.ipaddr),
|
||||
API_EXPR_REF(msg->msg.add.netmask),
|
||||
API_EXPR_REF(msg->msg.add.gw),
|
||||
#endif /* LWIP_IPV4 */
|
||||
msg->msg.add.state,
|
||||
msg->msg.add.init,
|
||||
msg->msg.add.input)) {
|
||||
return ERR_IF;
|
||||
} else {
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_IPV4
|
||||
/**
|
||||
* Call netif_set_addr() inside the tcpip_thread context.
|
||||
*/
|
||||
static err_t
|
||||
netifapi_do_netif_set_addr(struct tcpip_api_call_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;
|
||||
|
||||
netif_set_addr( msg->netif,
|
||||
API_EXPR_REF(msg->msg.add.ipaddr),
|
||||
API_EXPR_REF(msg->msg.add.netmask),
|
||||
API_EXPR_REF(msg->msg.add.gw));
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/**
|
||||
* Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
static err_t
|
||||
netifapi_do_netif_common(struct tcpip_api_call_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;
|
||||
|
||||
if (msg->msg.common.errtfunc != NULL) {
|
||||
return msg->msg.common.errtfunc(msg->netif);
|
||||
} else {
|
||||
msg->msg.common.voidfunc(msg->netif);
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netifapi_netif
|
||||
* Call netif_add() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*
|
||||
* @note for params @see netif_add()
|
||||
*/
|
||||
err_t
|
||||
netifapi_netif_add(struct netif *netif,
|
||||
#if LWIP_IPV4
|
||||
const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
|
||||
#endif /* LWIP_IPV4 */
|
||||
void *state, netif_init_fn init, netif_input_fn input)
|
||||
{
|
||||
err_t err;
|
||||
NETIFAPI_VAR_DECLARE(msg);
|
||||
NETIFAPI_VAR_ALLOC(msg);
|
||||
|
||||
#if LWIP_IPV4
|
||||
if (ipaddr == NULL) {
|
||||
ipaddr = IP4_ADDR_ANY4;
|
||||
}
|
||||
if (netmask == NULL) {
|
||||
netmask = IP4_ADDR_ANY4;
|
||||
}
|
||||
if (gw == NULL) {
|
||||
gw = IP4_ADDR_ANY4;
|
||||
}
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
NETIFAPI_VAR_REF(msg).netif = netif;
|
||||
#if LWIP_IPV4
|
||||
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
|
||||
#endif /* LWIP_IPV4 */
|
||||
NETIFAPI_VAR_REF(msg).msg.add.state = state;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.init = init;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.input = input;
|
||||
err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
|
||||
NETIFAPI_VAR_FREE(msg);
|
||||
return err;
|
||||
}
|
||||
|
||||
#if LWIP_IPV4
|
||||
/**
|
||||
* @ingroup netifapi_netif
|
||||
* Call netif_set_addr() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*
|
||||
* @note for params @see netif_set_addr()
|
||||
*/
|
||||
err_t
|
||||
netifapi_netif_set_addr(struct netif *netif,
|
||||
const ip4_addr_t *ipaddr,
|
||||
const ip4_addr_t *netmask,
|
||||
const ip4_addr_t *gw)
|
||||
{
|
||||
err_t err;
|
||||
NETIFAPI_VAR_DECLARE(msg);
|
||||
NETIFAPI_VAR_ALLOC(msg);
|
||||
|
||||
if (ipaddr == NULL) {
|
||||
ipaddr = IP4_ADDR_ANY4;
|
||||
}
|
||||
if (netmask == NULL) {
|
||||
netmask = IP4_ADDR_ANY4;
|
||||
}
|
||||
if (gw == NULL) {
|
||||
gw = IP4_ADDR_ANY4;
|
||||
}
|
||||
|
||||
NETIFAPI_VAR_REF(msg).netif = netif;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
|
||||
err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
|
||||
NETIFAPI_VAR_FREE(msg);
|
||||
return err;
|
||||
}
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/**
|
||||
* call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
|
||||
* way by running that function inside the tcpip_thread context.
|
||||
*
|
||||
* @note use only for functions where there is only "netif" parameter.
|
||||
*/
|
||||
err_t
|
||||
netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
|
||||
netifapi_errt_fn errtfunc)
|
||||
{
|
||||
err_t err;
|
||||
NETIFAPI_VAR_DECLARE(msg);
|
||||
NETIFAPI_VAR_ALLOC(msg);
|
||||
|
||||
NETIFAPI_VAR_REF(msg).netif = netif;
|
||||
NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc;
|
||||
NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc;
|
||||
err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call);
|
||||
NETIFAPI_VAR_FREE(msg);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LWIP_NETIF_API */
|
||||
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
* @file
|
||||
* Point To Point Protocol Sequential API module
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/pppapi.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "netif/ppp/pppol2tp.h"
|
||||
#include "netif/ppp/pppos.h"
|
||||
|
||||
/**
|
||||
* Call ppp_set_default() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_set_default(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
ppp_set_default(msg->ppp);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_set_default() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
void
|
||||
pppapi_set_default(ppp_pcb *pcb)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_set_default;
|
||||
msg.msg.ppp = pcb;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call ppp_set_auth() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_set_auth(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
ppp_set_auth(msg->ppp, msg->msg.setauth.authtype,
|
||||
msg->msg.setauth.user, msg->msg.setauth.passwd);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_set_auth() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
void
|
||||
pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_set_auth;
|
||||
msg.msg.ppp = pcb;
|
||||
msg.msg.msg.setauth.authtype = authtype;
|
||||
msg.msg.msg.setauth.user = user;
|
||||
msg.msg.msg.setauth.passwd = passwd;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
}
|
||||
|
||||
|
||||
#if PPP_NOTIFY_PHASE
|
||||
/**
|
||||
* Call ppp_set_notify_phase_callback() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_set_notify_phase_callback(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
ppp_set_notify_phase_callback(msg->ppp, msg->msg.setnotifyphasecb.notify_phase_cb);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_set_notify_phase_callback() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
void
|
||||
pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_set_notify_phase_callback;
|
||||
msg.msg.ppp = pcb;
|
||||
msg.msg.msg.setnotifyphasecb.notify_phase_cb = notify_phase_cb;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
}
|
||||
#endif /* PPP_NOTIFY_PHASE */
|
||||
|
||||
|
||||
#if PPPOS_SUPPORT
|
||||
/**
|
||||
* Call pppos_create() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_pppos_create(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
msg->ppp = pppos_create(msg->msg.serialcreate.pppif, msg->msg.serialcreate.output_cb,
|
||||
msg->msg.serialcreate.link_status_cb, msg->msg.serialcreate.ctx_cb);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call pppos_create() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
ppp_pcb*
|
||||
pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb,
|
||||
ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_pppos_create;
|
||||
msg.msg.msg.serialcreate.pppif = pppif;
|
||||
msg.msg.msg.serialcreate.output_cb = output_cb;
|
||||
msg.msg.msg.serialcreate.link_status_cb = link_status_cb;
|
||||
msg.msg.msg.serialcreate.ctx_cb = ctx_cb;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.ppp;
|
||||
}
|
||||
#endif /* PPPOS_SUPPORT */
|
||||
|
||||
|
||||
#if PPPOE_SUPPORT
|
||||
/**
|
||||
* Call pppoe_create() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_pppoe_create(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
|
||||
msg->ppp = pppoe_create(msg->msg.ethernetcreate.pppif, msg->msg.ethernetcreate.ethif,
|
||||
msg->msg.ethernetcreate.service_name, msg->msg.ethernetcreate.concentrator_name,
|
||||
msg->msg.ethernetcreate.link_status_cb, msg->msg.ethernetcreate.ctx_cb);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call pppoe_create() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
ppp_pcb*
|
||||
pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name,
|
||||
const char *concentrator_name, ppp_link_status_cb_fn link_status_cb,
|
||||
void *ctx_cb)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_pppoe_create;
|
||||
msg.msg.msg.ethernetcreate.pppif = pppif;
|
||||
msg.msg.msg.ethernetcreate.ethif = ethif;
|
||||
msg.msg.msg.ethernetcreate.service_name = service_name;
|
||||
msg.msg.msg.ethernetcreate.concentrator_name = concentrator_name;
|
||||
msg.msg.msg.ethernetcreate.link_status_cb = link_status_cb;
|
||||
msg.msg.msg.ethernetcreate.ctx_cb = ctx_cb;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.ppp;
|
||||
}
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
|
||||
|
||||
#if PPPOL2TP_SUPPORT
|
||||
/**
|
||||
* Call pppol2tp_create() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_pppol2tp_create(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
msg->ppp = pppol2tp_create(msg->msg.l2tpcreate.pppif,
|
||||
msg->msg.l2tpcreate.netif, msg->msg.l2tpcreate.ipaddr, msg->msg.l2tpcreate.port,
|
||||
#if PPPOL2TP_AUTH_SUPPORT
|
||||
msg->msg.l2tpcreate.secret,
|
||||
msg->msg.l2tpcreate.secret_len,
|
||||
#else /* PPPOL2TP_AUTH_SUPPORT */
|
||||
NULL,
|
||||
#endif /* PPPOL2TP_AUTH_SUPPORT */
|
||||
msg->msg.l2tpcreate.link_status_cb, msg->msg.l2tpcreate.ctx_cb);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call pppol2tp_create() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
ppp_pcb*
|
||||
pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port,
|
||||
const u8_t *secret, u8_t secret_len,
|
||||
ppp_link_status_cb_fn link_status_cb, void *ctx_cb)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_pppol2tp_create;
|
||||
msg.msg.msg.l2tpcreate.pppif = pppif;
|
||||
msg.msg.msg.l2tpcreate.netif = netif;
|
||||
msg.msg.msg.l2tpcreate.ipaddr = ipaddr;
|
||||
msg.msg.msg.l2tpcreate.port = port;
|
||||
#if PPPOL2TP_AUTH_SUPPORT
|
||||
msg.msg.msg.l2tpcreate.secret = secret;
|
||||
msg.msg.msg.l2tpcreate.secret_len = secret_len;
|
||||
#endif /* PPPOL2TP_AUTH_SUPPORT */
|
||||
msg.msg.msg.l2tpcreate.link_status_cb = link_status_cb;
|
||||
msg.msg.msg.l2tpcreate.ctx_cb = ctx_cb;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.ppp;
|
||||
}
|
||||
#endif /* PPPOL2TP_SUPPORT */
|
||||
|
||||
|
||||
/**
|
||||
* Call ppp_connect() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_connect(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
msg->err = ppp_connect(msg->ppp, msg->msg.connect.holdoff);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_connect() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
err_t
|
||||
pppapi_connect(ppp_pcb *pcb, u16_t holdoff)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_connect;
|
||||
msg.msg.ppp = pcb;
|
||||
msg.msg.msg.connect.holdoff = holdoff;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.err;
|
||||
}
|
||||
|
||||
|
||||
#if PPP_SERVER
|
||||
/**
|
||||
* Call ppp_listen() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_listen(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
msg->err = ppp_listen(msg->ppp, msg->msg.listen.addrs);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_listen() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
err_t
|
||||
pppapi_listen(ppp_pcb *pcb, struct ppp_addrs *addrs)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_listen;
|
||||
msg.msg.ppp = pcb;
|
||||
msg.msg.msg.listen.addrs = addrs;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.err;
|
||||
}
|
||||
#endif /* PPP_SERVER */
|
||||
|
||||
|
||||
/**
|
||||
* Call ppp_close() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_close(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
msg->err = ppp_close(msg->ppp, msg->msg.close.nocarrier);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_close() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
err_t
|
||||
pppapi_close(ppp_pcb *pcb, u8_t nocarrier)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_close;
|
||||
msg.msg.ppp = pcb;
|
||||
msg.msg.msg.close.nocarrier = nocarrier;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call ppp_free() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_free(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
msg->err = ppp_free(msg->ppp);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_free() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
err_t
|
||||
pppapi_free(ppp_pcb *pcb)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_free;
|
||||
msg.msg.ppp = pcb;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call ppp_ioctl() inside the tcpip_thread context.
|
||||
*/
|
||||
static void
|
||||
pppapi_do_ppp_ioctl(struct pppapi_msg_msg *msg)
|
||||
{
|
||||
msg->err = ppp_ioctl(msg->ppp, msg->msg.ioctl.cmd, msg->msg.ioctl.arg);
|
||||
TCPIP_PPPAPI_ACK(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call ppp_ioctl() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*/
|
||||
err_t
|
||||
pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg)
|
||||
{
|
||||
struct pppapi_msg msg;
|
||||
msg.function = pppapi_do_ppp_ioctl;
|
||||
msg.msg.ppp = pcb;
|
||||
msg.msg.msg.ioctl.cmd = cmd;
|
||||
msg.msg.msg.ioctl.arg = arg;
|
||||
TCPIP_PPPAPI(&msg);
|
||||
return msg.msg.err;
|
||||
}
|
||||
|
||||
|
||||
#endif /* LWIP_PPP_API */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,552 @@
|
||||
/**
|
||||
* @file
|
||||
* Sequential API Main thread module
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/init.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name)
|
||||
#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name)
|
||||
#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)
|
||||
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
|
||||
|
||||
/* global variables */
|
||||
static tcpip_init_done_fn tcpip_init_done;
|
||||
static void *tcpip_init_done_arg;
|
||||
static sys_mbox_t mbox;
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
/** The global semaphore to lock the stack. */
|
||||
sys_mutex_t lock_tcpip_core;
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
|
||||
#if LWIP_TIMERS
|
||||
/* wait for a message, timeouts are processed while waiting */
|
||||
#define TCPIP_MBOX_FETCH(mbox, msg) sys_timeouts_mbox_fetch(mbox, msg)
|
||||
#else /* LWIP_TIMERS */
|
||||
/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
|
||||
#define TCPIP_MBOX_FETCH(mbox, msg) sys_mbox_fetch(mbox, msg)
|
||||
#endif /* LWIP_TIMERS */
|
||||
|
||||
/**
|
||||
* The main lwIP thread. This thread has exclusive access to lwIP core functions
|
||||
* (unless access to them is not locked). Other threads communicate with this
|
||||
* thread using message boxes.
|
||||
*
|
||||
* It also starts all the timers to make sure they are running in the right
|
||||
* thread context.
|
||||
*
|
||||
* @param arg unused argument
|
||||
*/
|
||||
static void
|
||||
tcpip_thread(void *arg)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
|
||||
if (tcpip_init_done != NULL) {
|
||||
tcpip_init_done(tcpip_init_done_arg);
|
||||
}
|
||||
|
||||
LOCK_TCPIP_CORE();
|
||||
while (1) { /* MAIN Loop */
|
||||
UNLOCK_TCPIP_CORE();
|
||||
LWIP_TCPIP_THREAD_ALIVE();
|
||||
/* wait for a message, timeouts are processed while waiting */
|
||||
TCPIP_MBOX_FETCH(&mbox, (void **)&msg);
|
||||
LOCK_TCPIP_CORE();
|
||||
if (msg == NULL) {
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
|
||||
LWIP_ASSERT("tcpip_thread: invalid message", 0);
|
||||
continue;
|
||||
}
|
||||
switch (msg->type) {
|
||||
#if !LWIP_TCPIP_CORE_LOCKING
|
||||
case TCPIP_MSG_API:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
|
||||
msg->msg.api_msg.function(msg->msg.api_msg.msg);
|
||||
break;
|
||||
case TCPIP_MSG_API_CALL:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg));
|
||||
msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg);
|
||||
sys_sem_signal(msg->msg.api_call.sem);
|
||||
break;
|
||||
#endif /* !LWIP_TCPIP_CORE_LOCKING */
|
||||
|
||||
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
|
||||
case TCPIP_MSG_INPKT:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
|
||||
msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif);
|
||||
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
|
||||
break;
|
||||
#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
|
||||
|
||||
#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
|
||||
case TCPIP_MSG_TIMEOUT:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
|
||||
sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
break;
|
||||
case TCPIP_MSG_UNTIMEOUT:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
|
||||
sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
break;
|
||||
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
|
||||
|
||||
case TCPIP_MSG_CALLBACK:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
|
||||
msg->msg.cb.function(msg->msg.cb.ctx);
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
break;
|
||||
|
||||
case TCPIP_MSG_CALLBACK_STATIC:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
|
||||
msg->msg.cb.function(msg->msg.cb.ctx);
|
||||
break;
|
||||
|
||||
#if TLS_CONFIG_AP_OPT_FWD
|
||||
case TCPIP_MSG_OUTPKT:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: alg out_put PACKET %p\n", (void *)msg));
|
||||
etharp_output(msg->msg.outp.netif, msg->msg.outp.p, (ip4_addr_t *)&(msg->msg.outp.ipaddr));
|
||||
pbuf_free(msg->msg.outp.p);
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
|
||||
LWIP_ASSERT("tcpip_thread: invalid message", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if TLS_CONFIG_AP_OPT_FWD
|
||||
err_t tcpip_output(struct pbuf *p, struct netif *inp, ip_addr_t ipaddr)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
if (!sys_mbox_valid(&mbox)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
msg->type = TCPIP_MSG_OUTPKT;
|
||||
msg->msg.outp.p = p;
|
||||
msg->msg.outp.netif = inp;
|
||||
ip_addr_copy(msg->msg.outp.ipaddr, ipaddr);
|
||||
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Pass a received packet to tcpip_thread for input processing
|
||||
*
|
||||
* @param p the received packet
|
||||
* @param inp the network interface on which the packet was received
|
||||
* @param input_fn input function to call
|
||||
*/
|
||||
err_t
|
||||
tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
|
||||
{
|
||||
#if LWIP_TCPIP_CORE_LOCKING_INPUT
|
||||
err_t ret;
|
||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));
|
||||
LOCK_TCPIP_CORE();
|
||||
ret = input_fn(p, inp);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
return ret;
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));
|
||||
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
msg->type = TCPIP_MSG_INPKT;
|
||||
msg->msg.inp.p = p;
|
||||
msg->msg.inp.netif = inp;
|
||||
msg->msg.inp.input_fn = input_fn;
|
||||
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
|
||||
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_OK;
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup lwip_os
|
||||
* Pass a received packet to tcpip_thread for input processing with
|
||||
* ethernet_input or ip_input. Don't call directly, pass to netif_add()
|
||||
* and call netif->input().
|
||||
*
|
||||
* @param p the received packet, p->payload pointing to the Ethernet header or
|
||||
* to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
|
||||
* NETIF_FLAG_ETHERNET flags)
|
||||
* @param inp the network interface on which the packet was received
|
||||
*/
|
||||
err_t
|
||||
tcpip_input(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
#if LWIP_ETHERNET
|
||||
if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
|
||||
return tcpip_inpkt(p, inp, ethernet_input);
|
||||
} else
|
||||
#endif /* LWIP_ETHERNET */
|
||||
return tcpip_inpkt(p, inp, ip_input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a specific function in the thread context of
|
||||
* tcpip_thread for easy access synchronization.
|
||||
* A function called in that way may access lwIP core code
|
||||
* without fearing concurrent access.
|
||||
*
|
||||
* @param function the function to call
|
||||
* @param ctx parameter passed to f
|
||||
* @param block 1 to block until the request is posted, 0 to non-blocking mode
|
||||
* @return ERR_OK if the function was called, another err_t if not
|
||||
*/
|
||||
err_t
|
||||
tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));
|
||||
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
msg->type = TCPIP_MSG_CALLBACK;
|
||||
msg->msg.cb.function = function;
|
||||
msg->msg.cb.ctx = ctx;
|
||||
if (block) {
|
||||
sys_mbox_post(&mbox, msg);
|
||||
} else {
|
||||
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
return ERR_MEM;
|
||||
}
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
|
||||
/**
|
||||
* call sys_timeout in tcpip_thread
|
||||
*
|
||||
* @param msecs time in milliseconds for timeout
|
||||
* @param h function to be called on timeout
|
||||
* @param arg argument to pass to timeout function h
|
||||
* @return ERR_MEM on memory error, ERR_OK otherwise
|
||||
*/
|
||||
err_t
|
||||
tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));
|
||||
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
msg->type = TCPIP_MSG_TIMEOUT;
|
||||
msg->msg.tmo.msecs = msecs;
|
||||
msg->msg.tmo.h = h;
|
||||
msg->msg.tmo.arg = arg;
|
||||
sys_mbox_post(&mbox, msg);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* call sys_untimeout in tcpip_thread
|
||||
*
|
||||
* @param h function to be called on timeout
|
||||
* @param arg argument to pass to timeout function h
|
||||
* @return ERR_MEM on memory error, ERR_OK otherwise
|
||||
*/
|
||||
err_t
|
||||
tcpip_untimeout(sys_timeout_handler h, void *arg)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));
|
||||
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
msg->type = TCPIP_MSG_UNTIMEOUT;
|
||||
msg->msg.tmo.h = h;
|
||||
msg->msg.tmo.arg = arg;
|
||||
sys_mbox_post(&mbox, msg);
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
|
||||
|
||||
|
||||
/**
|
||||
* Sends a message to TCPIP thread to call a function. Caller thread blocks on
|
||||
* on a provided semaphore, which ist NOT automatically signalled by TCPIP thread,
|
||||
* this has to be done by the user.
|
||||
* It is recommended to use LWIP_TCPIP_CORE_LOCKING since this is the way
|
||||
* with least runtime overhead.
|
||||
*
|
||||
* @param fn function to be called from TCPIP thread
|
||||
* @param apimsg argument to API function
|
||||
* @param sem semaphore to wait on
|
||||
* @return ERR_OK if the function was called, another err_t if not
|
||||
*/
|
||||
err_t
|
||||
tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem)
|
||||
{
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
LWIP_UNUSED_ARG(sem);
|
||||
LOCK_TCPIP_CORE();
|
||||
fn(apimsg);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
return ERR_OK;
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
TCPIP_MSG_VAR_DECLARE(msg);
|
||||
|
||||
LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));
|
||||
|
||||
TCPIP_MSG_VAR_ALLOC(msg);
|
||||
TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API;
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_msg.function = fn;
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_msg.msg = apimsg;
|
||||
sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg));
|
||||
sys_arch_sem_wait(sem, 0);
|
||||
TCPIP_MSG_VAR_FREE(msg);
|
||||
return ERR_OK;
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously calls function in TCPIP thread and waits for its completion.
|
||||
* It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or
|
||||
* LWIP_NETCONN_SEM_PER_THREAD.
|
||||
* If not, a semaphore is created and destroyed on every call which is usually
|
||||
* an expensive/slow operation.
|
||||
* @param fn Function to call
|
||||
* @param call Call parameters
|
||||
* @return Return value from tcpip_api_call_fn
|
||||
*/
|
||||
err_t
|
||||
tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
|
||||
{
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
err_t err;
|
||||
LOCK_TCPIP_CORE();
|
||||
err = fn(call);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
return err;
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
TCPIP_MSG_VAR_DECLARE(msg);
|
||||
|
||||
#if !LWIP_NETCONN_SEM_PER_THREAD
|
||||
err_t err = sys_sem_new(&call->sem, 0);
|
||||
if (err != ERR_OK) {
|
||||
return err;
|
||||
}
|
||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));
|
||||
|
||||
TCPIP_MSG_VAR_ALLOC(msg);
|
||||
TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API_CALL;
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_call.arg = call;
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn;
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET();
|
||||
#else /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem;
|
||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg));
|
||||
sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0);
|
||||
TCPIP_MSG_VAR_FREE(msg);
|
||||
|
||||
#if !LWIP_NETCONN_SEM_PER_THREAD
|
||||
sys_sem_free(&call->sem);
|
||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
|
||||
return call->err;
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a structure for a static callback message and initialize it.
|
||||
* This is intended to be used to send "static" messages from interrupt context.
|
||||
*
|
||||
* @param function the function to call
|
||||
* @param ctx parameter passed to function
|
||||
* @return a struct pointer to pass to tcpip_trycallback().
|
||||
*/
|
||||
struct tcpip_callback_msg*
|
||||
tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
|
||||
{
|
||||
struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
msg->type = TCPIP_MSG_CALLBACK_STATIC;
|
||||
msg->msg.cb.function = function;
|
||||
msg->msg.cb.ctx = ctx;
|
||||
return (struct tcpip_callback_msg*)msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a callback message allocated by tcpip_callbackmsg_new().
|
||||
*
|
||||
* @param msg the message to free
|
||||
*/
|
||||
void
|
||||
tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg)
|
||||
{
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to post a callback-message to the tcpip_thread mbox
|
||||
* This is intended to be used to send "static" messages from interrupt context.
|
||||
*
|
||||
* @param msg pointer to the message to post
|
||||
* @return sys_mbox_trypost() return code
|
||||
*/
|
||||
err_t
|
||||
tcpip_trycallback(struct tcpip_callback_msg* msg)
|
||||
{
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));
|
||||
return sys_mbox_trypost(&mbox, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup lwip_os
|
||||
* Initialize this module:
|
||||
* - initialize all sub modules
|
||||
* - start the tcpip_thread
|
||||
*
|
||||
* @param initfunc a function to call when tcpip_thread is running and finished initializing
|
||||
* @param arg argument to pass to initfunc
|
||||
*/
|
||||
void
|
||||
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
|
||||
{
|
||||
lwip_init();
|
||||
|
||||
tcpip_init_done = initfunc;
|
||||
tcpip_init_done_arg = arg;
|
||||
if (sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
|
||||
LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
|
||||
}
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
|
||||
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
|
||||
}
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
|
||||
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple callback function used with tcpip_callback to free a pbuf
|
||||
* (pbuf_free has a wrong signature for tcpip_callback)
|
||||
*
|
||||
* @param p The pbuf (chain) to be dereferenced.
|
||||
*/
|
||||
static void
|
||||
pbuf_free_int(void *p)
|
||||
{
|
||||
struct pbuf *q = (struct pbuf *)p;
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple wrapper function that allows you to free a pbuf from interrupt context.
|
||||
*
|
||||
* @param p The pbuf (chain) to be dereferenced.
|
||||
* @return ERR_OK if callback could be enqueued, an err_t if not
|
||||
*/
|
||||
err_t
|
||||
pbuf_free_callback(struct pbuf *p)
|
||||
{
|
||||
return tcpip_callback_with_block(pbuf_free_int, p, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple wrapper function that allows you to free heap memory from
|
||||
* interrupt context.
|
||||
*
|
||||
* @param m the heap memory to free
|
||||
* @return ERR_OK if callback could be enqueued, an err_t if not
|
||||
*/
|
||||
err_t
|
||||
mem_free_callback(void *m)
|
||||
{
|
||||
return tcpip_callback_with_block(mem_free, m, 0);
|
||||
}
|
||||
|
||||
#endif /* !NO_SYS */
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/apps/httpd_opts.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/apps/fs.h"
|
||||
#include "fsdata.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if HTTPD_USE_CUSTOM_FSDATA
|
||||
#include "fsdata_custom.c"
|
||||
#else /* HTTPD_USE_CUSTOM_FSDATA */
|
||||
#include "fsdata.c"
|
||||
#endif /* HTTPD_USE_CUSTOM_FSDATA */
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
#if LWIP_HTTPD_CUSTOM_FILES
|
||||
int fs_open_custom(struct fs_file *file, const char *name);
|
||||
void fs_close_custom(struct fs_file *file);
|
||||
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||
u8_t fs_canread_custom(struct fs_file *file);
|
||||
u8_t fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
|
||||
int fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg);
|
||||
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
int fs_read_custom(struct fs_file *file, char *buffer, int count);
|
||||
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
fs_open(struct fs_file *file, const char *name)
|
||||
{
|
||||
const struct fsdata_file *f;
|
||||
|
||||
if ((file == NULL) || (name == NULL)) {
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
#if LWIP_HTTPD_CUSTOM_FILES
|
||||
if (fs_open_custom(file, name)) {
|
||||
file->is_custom_file = 1;
|
||||
return ERR_OK;
|
||||
}
|
||||
file->is_custom_file = 0;
|
||||
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||
|
||||
for (f = FS_ROOT; f != NULL; f = f->next) {
|
||||
if (!strcmp(name, (const char *)f->name)) {
|
||||
file->data = (const char *)f->data;
|
||||
file->len = f->len;
|
||||
file->index = f->len;
|
||||
file->pextension = NULL;
|
||||
file->flags = f->flags;
|
||||
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||
file->chksum_count = f->chksum_count;
|
||||
file->chksum = f->chksum;
|
||||
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||
#if LWIP_HTTPD_FILE_STATE
|
||||
file->state = fs_state_init(file, name);
|
||||
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
/* file not found */
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
fs_close(struct fs_file *file)
|
||||
{
|
||||
#if LWIP_HTTPD_CUSTOM_FILES
|
||||
if (file->is_custom_file) {
|
||||
fs_close_custom(file);
|
||||
}
|
||||
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||
#if LWIP_HTTPD_FILE_STATE
|
||||
fs_state_free(file, file->state);
|
||||
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||
LWIP_UNUSED_ARG(file);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if LWIP_HTTPD_DYNAMIC_FILE_READ
|
||||
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||
int
|
||||
fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
|
||||
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
int
|
||||
fs_read(struct fs_file *file, char *buffer, int count)
|
||||
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
{
|
||||
int read;
|
||||
if(file->index == file->len) {
|
||||
return FS_READ_EOF;
|
||||
}
|
||||
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||
LWIP_UNUSED_ARG(callback_fn);
|
||||
LWIP_UNUSED_ARG(callback_arg);
|
||||
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
#if LWIP_HTTPD_CUSTOM_FILES
|
||||
if (file->is_custom_file) {
|
||||
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||
return fs_read_async_custom(file, buffer, count, callback_fn, callback_arg);
|
||||
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
return fs_read_custom(file, buffer, count);
|
||||
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
}
|
||||
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||
|
||||
read = file->len - file->index;
|
||||
if(read > count) {
|
||||
read = count;
|
||||
}
|
||||
|
||||
MEMCPY(buffer, (file->data + file->index), read);
|
||||
file->index += read;
|
||||
|
||||
return(read);
|
||||
}
|
||||
#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||
int
|
||||
fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
|
||||
{
|
||||
if (file != NULL) {
|
||||
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||
#if LWIP_HTTPD_CUSTOM_FILES
|
||||
if (!fs_canread_custom(file)) {
|
||||
if (fs_wait_read_custom(file, callback_fn, callback_arg)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else /* LWIP_HTTPD_CUSTOM_FILES */
|
||||
LWIP_UNUSED_ARG(callback_fn);
|
||||
LWIP_UNUSED_ARG(callback_arg);
|
||||
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
int
|
||||
fs_bytes_left(struct fs_file *file)
|
||||
{
|
||||
return file->len - file->index;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<html>
|
||||
<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
|
||||
<body bgcolor="white" text="black">
|
||||
|
||||
<table width="100%">
|
||||
<tr valign="top"><td width="80">
|
||||
<a href="http://www.sics.se/"><img src="/img/sics.gif"
|
||||
border="0" alt="SICS logo" title="SICS logo"></a>
|
||||
</td><td width="500">
|
||||
<h1>lwIP - A Lightweight TCP/IP Stack</h1>
|
||||
<h2>404 - Page not found</h2>
|
||||
<p>
|
||||
Sorry, the page you are requesting was not found on this
|
||||
server.
|
||||
</p>
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 724 B |
@@ -0,0 +1,47 @@
|
||||
<html>
|
||||
<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
|
||||
<body bgcolor="white" text="black">
|
||||
|
||||
<table width="100%">
|
||||
<tr valign="top"><td width="80">
|
||||
<a href="http://www.sics.se/"><img src="/img/sics.gif"
|
||||
border="0" alt="SICS logo" title="SICS logo"></a>
|
||||
</td><td width="500">
|
||||
<h1>lwIP - A Lightweight TCP/IP Stack</h1>
|
||||
<p>
|
||||
The web page you are watching was served by a simple web
|
||||
server running on top of the lightweight TCP/IP stack <a
|
||||
href="http://www.sics.se/~adam/lwip/">lwIP</a>.
|
||||
</p>
|
||||
<p>
|
||||
lwIP is an open source implementation of the TCP/IP
|
||||
protocol suite that was originally written by <a
|
||||
href="http://www.sics.se/~adam/lwip/">Adam Dunkels
|
||||
of the Swedish Institute of Computer Science</a> but now is
|
||||
being actively developed by a team of developers
|
||||
distributed world-wide. Since it's release, lwIP has
|
||||
spurred a lot of interest and has been ported to several
|
||||
platforms and operating systems. lwIP can be used either
|
||||
with or without an underlying OS.
|
||||
</p>
|
||||
<p>
|
||||
The focus of the lwIP TCP/IP implementation is to reduce
|
||||
the RAM usage while still having a full scale TCP. This
|
||||
makes lwIP suitable for use in embedded systems with tens
|
||||
of kilobytes of free RAM and room for around 40 kilobytes
|
||||
of code ROM.
|
||||
</p>
|
||||
<p>
|
||||
More information about lwIP can be found at the lwIP
|
||||
homepage at <a
|
||||
href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
|
||||
or at the lwIP wiki at <a
|
||||
href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
|
||||
</p>
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
#include "lwip/apps/fs.h"
|
||||
#include "lwip/def.h"
|
||||
#include "fsdata.h"
|
||||
|
||||
|
||||
#define file_NULL (struct fsdata_file *) NULL
|
||||
|
||||
|
||||
static const unsigned int dummy_align__img_sics_gif = 0;
|
||||
static const unsigned char data__img_sics_gif[] = {
|
||||
/* /img/sics.gif (14 chars) */
|
||||
0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x00,0x00,0x00,
|
||||
|
||||
/* HTTP header */
|
||||
/* "HTTP/1.0 200 OK
|
||||
" (17 bytes) */
|
||||
0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
|
||||
0x0a,
|
||||
/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)
|
||||
" (63 bytes) */
|
||||
0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33,
|
||||
0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
|
||||
0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
|
||||
0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
|
||||
/* "Content-type: image/gif
|
||||
|
||||
" (27 bytes) */
|
||||
0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d,
|
||||
0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x0d,0x0a,0x0d,0x0a,
|
||||
/* raw file data (724 bytes) */
|
||||
0x47,0x49,0x46,0x38,0x39,0x61,0x46,0x00,0x22,0x00,0xa5,0x00,0x00,0xd9,0x2b,0x39,
|
||||
0x6a,0x6a,0x6a,0xbf,0xbf,0xbf,0x93,0x93,0x93,0x0f,0x0f,0x0f,0xb0,0xb0,0xb0,0xa6,
|
||||
0xa6,0xa6,0x80,0x80,0x80,0x76,0x76,0x76,0x1e,0x1e,0x1e,0x9d,0x9d,0x9d,0x2e,0x2e,
|
||||
0x2e,0x49,0x49,0x49,0x54,0x54,0x54,0x8a,0x8a,0x8a,0x60,0x60,0x60,0xc6,0xa6,0x99,
|
||||
0xbd,0xb5,0xb2,0xc2,0xab,0xa1,0xd9,0x41,0x40,0xd5,0x67,0x55,0xc0,0xb0,0xaa,0xd5,
|
||||
0x5e,0x4e,0xd6,0x50,0x45,0xcc,0x93,0x7d,0xc8,0xa1,0x90,0xce,0x8b,0x76,0xd2,0x7b,
|
||||
0x65,0xd1,0x84,0x6d,0xc9,0x99,0x86,0x3a,0x3a,0x3a,0x00,0x00,0x00,0xb8,0xb8,0xb8,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,
|
||||
0x00,0x00,0x46,0x00,0x22,0x00,0x00,0x06,0xfe,0x40,0x90,0x70,0x48,0x2c,0x1a,0x8f,
|
||||
0xc8,0xa4,0x72,0xc9,0x6c,0x3a,0x9f,0xd0,0xa8,0x74,0x4a,0xad,0x5a,0xaf,0xd8,0xac,
|
||||
0x76,0xa9,0x40,0x04,0xbe,0x83,0xe2,0x60,0x3c,0x50,0x20,0x0d,0x8e,0x6f,0x00,0x31,
|
||||
0x28,0x1c,0x0d,0x07,0xb5,0xc3,0x60,0x75,0x24,0x3e,0xf8,0xfc,0x87,0x11,0x06,0xe9,
|
||||
0x3d,0x46,0x07,0x0b,0x7a,0x7a,0x7c,0x43,0x06,0x1e,0x84,0x78,0x0b,0x07,0x6e,0x51,
|
||||
0x01,0x8a,0x84,0x08,0x7e,0x79,0x80,0x87,0x89,0x91,0x7a,0x93,0x0a,0x04,0x99,0x78,
|
||||
0x96,0x4f,0x03,0x9e,0x79,0x01,0x94,0x9f,0x43,0x9c,0xa3,0xa4,0x05,0x77,0xa3,0xa0,
|
||||
0x4e,0x98,0x79,0x0b,0x1e,0x83,0xa4,0xa6,0x1f,0x96,0x05,0x9d,0xaa,0x78,0x01,0x07,
|
||||
0x84,0x04,0x1e,0x1e,0xbb,0xb8,0x51,0x84,0x0e,0x43,0x05,0x07,0x77,0xa5,0x7f,0x42,
|
||||
0xb1,0xb2,0x01,0x63,0x08,0x0d,0xbb,0x01,0x0c,0x7a,0x0d,0x44,0x0e,0xd8,0xaf,0x4c,
|
||||
0x05,0x7a,0x04,0x47,0x07,0x07,0xb7,0x80,0xa2,0xe1,0x7d,0x44,0x05,0x01,0x04,0x01,
|
||||
0xd0,0xea,0x87,0x93,0x4f,0xe0,0x9a,0x49,0xce,0xd8,0x79,0x04,0x66,0x20,0x15,0x10,
|
||||
0x10,0x11,0x92,0x29,0x80,0xb6,0xc0,0x91,0x15,0x45,0x1e,0x90,0x19,0x71,0x46,0xa8,
|
||||
0x5c,0x04,0x0e,0x00,0x22,0x4e,0xe8,0x40,0x24,0x9f,0x3e,0x04,0x06,0xa7,0x58,0xd4,
|
||||
0x93,0xa0,0x1c,0x91,0x3f,0xe8,0xf0,0x88,0x03,0xb1,0x21,0xa2,0x49,0x00,0x19,0x86,
|
||||
0xfc,0x52,0x44,0xe0,0x01,0x9d,0x29,0x21,0x15,0x25,0x50,0xf7,0x67,0x25,0x1e,0x06,
|
||||
0xfd,0x4e,0x9a,0xb4,0x90,0xac,0x15,0xfa,0xcb,0x52,0x53,0x1e,0x8c,0xf2,0xf8,0x07,
|
||||
0x92,0x2d,0x08,0x3a,0x4d,0x12,0x49,0x95,0x49,0xdb,0x14,0x04,0xc4,0x14,0x85,0x29,
|
||||
0xaa,0xe7,0x01,0x08,0xa4,0x49,0x01,0x14,0x51,0xe0,0x53,0x91,0xd5,0x29,0x06,0x1a,
|
||||
0x64,0x02,0xf4,0xc7,0x81,0x9e,0x05,0x20,0x22,0x64,0xa5,0x30,0xae,0xab,0x9e,0x97,
|
||||
0x53,0xd8,0xb9,0xfd,0x50,0xef,0x93,0x02,0x42,0x74,0x34,0xe8,0x9c,0x20,0x21,0xc9,
|
||||
0x01,0x68,0x78,0xe6,0x55,0x29,0x20,0x56,0x4f,0x4c,0x40,0x51,0x71,0x82,0xc0,0x70,
|
||||
0x21,0x22,0x85,0xbe,0x4b,0x1c,0x44,0x05,0xea,0xa4,0x01,0xbf,0x22,0xb5,0xf0,0x1c,
|
||||
0x06,0x51,0x38,0x8f,0xe0,0x22,0xec,0x18,0xac,0x39,0x22,0xd4,0xd6,0x93,0x44,0x01,
|
||||
0x32,0x82,0xc8,0xfc,0x61,0xb3,0x01,0x45,0x0c,0x2e,0x83,0x30,0xd0,0x0e,0x17,0x24,
|
||||
0x0f,0x70,0x85,0x94,0xee,0x05,0x05,0x53,0x4b,0x32,0x1b,0x3f,0x98,0xd3,0x1d,0x29,
|
||||
0x81,0xb0,0xae,0x1e,0x8c,0x7e,0x68,0xe0,0x60,0x5a,0x54,0x8f,0xb0,0x78,0x69,0x73,
|
||||
0x06,0xa2,0x00,0x6b,0x57,0xca,0x3d,0x11,0x50,0xbd,0x04,0x30,0x4b,0x3a,0xd4,0xab,
|
||||
0x5f,0x1f,0x9b,0x3d,0x13,0x74,0x27,0x88,0x3c,0x25,0xe0,0x17,0xbe,0x7a,0x79,0x45,
|
||||
0x0d,0x0c,0xb0,0x8b,0xda,0x90,0xca,0x80,0x06,0x5d,0x17,0x60,0x1c,0x22,0x4c,0xd8,
|
||||
0x57,0x22,0x06,0x20,0x00,0x98,0x07,0x08,0xe4,0x56,0x80,0x80,0x1c,0xc5,0xb7,0xc5,
|
||||
0x82,0x0c,0x36,0xe8,0xe0,0x83,0x10,0x46,0x28,0xe1,0x84,0x14,0x56,0x68,0xa1,0x10,
|
||||
0x41,0x00,0x00,0x3b,};
|
||||
|
||||
static const unsigned int dummy_align__404_html = 1;
|
||||
static const unsigned char data__404_html[] = {
|
||||
/* /404.html (10 chars) */
|
||||
0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
|
||||
|
||||
/* HTTP header */
|
||||
/* "HTTP/1.0 404 File not found
|
||||
" (29 bytes) */
|
||||
0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c,
|
||||
0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a,
|
||||
/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)
|
||||
" (63 bytes) */
|
||||
0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33,
|
||||
0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
|
||||
0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
|
||||
0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
|
||||
/* "Content-type: text/html
|
||||
|
||||
" (27 bytes) */
|
||||
0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
|
||||
0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
|
||||
/* raw file data (565 bytes) */
|
||||
0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
|
||||
0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
|
||||
0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
|
||||
0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
|
||||
0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
|
||||
0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
|
||||
0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
|
||||
0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
|
||||
0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
|
||||
0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
|
||||
0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
|
||||
0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
|
||||
0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
|
||||
0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
|
||||
0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
|
||||
0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
|
||||
0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
|
||||
0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
|
||||
0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
|
||||
0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
|
||||
0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
|
||||
0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
|
||||
0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
|
||||
0x20,0x3c,0x68,0x32,0x3e,0x34,0x30,0x34,0x20,0x2d,0x20,0x50,0x61,0x67,0x65,0x20,
|
||||
0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x32,0x3e,0x0d,0x0a,
|
||||
0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x53,0x6f,0x72,
|
||||
0x72,0x79,0x2c,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,
|
||||
0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x20,
|
||||
0x77,0x61,0x73,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x6f,0x6e,
|
||||
0x20,0x74,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,
|
||||
0x65,0x72,0x2e,0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
|
||||
0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
|
||||
0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
|
||||
0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
|
||||
0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
|
||||
0x6d,0x6c,0x3e,0x0d,0x0a,};
|
||||
|
||||
static const unsigned int dummy_align__index_html = 2;
|
||||
static const unsigned char data__index_html[] = {
|
||||
/* /index.html (12 chars) */
|
||||
0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
|
||||
|
||||
/* HTTP header */
|
||||
/* "HTTP/1.0 200 OK
|
||||
" (17 bytes) */
|
||||
0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
|
||||
0x0a,
|
||||
/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)
|
||||
" (63 bytes) */
|
||||
0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33,
|
||||
0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
|
||||
0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
|
||||
0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
|
||||
/* "Content-type: text/html
|
||||
|
||||
" (27 bytes) */
|
||||
0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
|
||||
0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
|
||||
/* raw file data (1751 bytes) */
|
||||
0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
|
||||
0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
|
||||
0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
|
||||
0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
|
||||
0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
|
||||
0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
|
||||
0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
|
||||
0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
|
||||
0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
|
||||
0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
|
||||
0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
|
||||
0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
|
||||
0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
|
||||
0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
|
||||
0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
|
||||
0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
|
||||
0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
|
||||
0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
|
||||
0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
|
||||
0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
|
||||
0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
|
||||
0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
|
||||
0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
|
||||
0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77,
|
||||
0x65,0x62,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20,
|
||||
0x77,0x61,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72,
|
||||
0x76,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,
|
||||
0x77,0x65,0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72,
|
||||
0x20,0x72,0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20,
|
||||
0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,
|
||||
0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20,
|
||||
0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
|
||||
0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
|
||||
0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c,
|
||||
0x77,0x49,0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
|
||||
0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
|
||||
0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,
|
||||
0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
|
||||
0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,
|
||||
0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,
|
||||
0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,
|
||||
0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,
|
||||
0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
|
||||
0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
|
||||
0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,
|
||||
0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,
|
||||
0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
|
||||
0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,
|
||||
0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,
|
||||
0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,
|
||||
0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,
|
||||
0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,
|
||||
0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,
|
||||
0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,
|
||||
0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,
|
||||
0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,
|
||||
0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,
|
||||
0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,
|
||||
0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,
|
||||
0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,
|
||||
0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,
|
||||
0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,
|
||||
0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,
|
||||
0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,
|
||||
0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,
|
||||
0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,
|
||||
0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,
|
||||
0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,
|
||||
0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,
|
||||
0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,0x6f,0x63,0x75,0x73,0x20,0x6f,
|
||||
0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x54,0x43,0x50,0x2f,0x49,
|
||||
0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
|
||||
0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,0x75,0x63,0x65,0x0d,0x0a,0x09,
|
||||
0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,0x4d,0x20,0x75,0x73,0x61,0x67,
|
||||
0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,0x69,0x6c,0x6c,0x20,0x68,0x61,
|
||||
0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x20,0x73,0x63,0x61,0x6c,
|
||||
0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
|
||||
0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,0x49,0x50,0x20,0x73,0x75,0x69,
|
||||
0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,0x75,0x73,0x65,0x20,0x69,0x6e,
|
||||
0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,
|
||||
0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,0x73,0x0d,0x0a,0x09,0x20,0x20,
|
||||
0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x20,0x6f,
|
||||
0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,0x20,0x61,0x6e,0x64,0x20,0x72,
|
||||
0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,0x6f,0x75,0x6e,0x64,0x20,0x34,
|
||||
0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a,0x09,0x20,0x20,
|
||||
0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,0x52,0x4f,0x4d,0x2e,0x0d,0x0a,
|
||||
0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
|
||||
0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72,
|
||||
0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x6c,0x77,0x49,
|
||||
0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x61,
|
||||
0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
|
||||
0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d,
|
||||
0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,
|
||||
0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,
|
||||
0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,
|
||||
0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,
|
||||
0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,
|
||||
0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f,
|
||||
0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x72,0x20,0x61,0x74,
|
||||
0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x77,0x69,0x6b,0x69,0x20,0x61,
|
||||
0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,
|
||||
0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,
|
||||
0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
|
||||
0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x3c,
|
||||
0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
|
||||
0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
|
||||
0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
|
||||
0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
|
||||
0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
|
||||
0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,};
|
||||
|
||||
|
||||
|
||||
const struct fsdata_file file__img_sics_gif[] = { {
|
||||
file_NULL,
|
||||
data__img_sics_gif,
|
||||
data__img_sics_gif + 16,
|
||||
sizeof(data__img_sics_gif) - 16,
|
||||
1,
|
||||
}};
|
||||
|
||||
const struct fsdata_file file__404_html[] = { {
|
||||
file__img_sics_gif,
|
||||
data__404_html,
|
||||
data__404_html + 12,
|
||||
sizeof(data__404_html) - 12,
|
||||
1,
|
||||
}};
|
||||
|
||||
const struct fsdata_file file__index_html[] = { {
|
||||
file__404_html,
|
||||
data__index_html,
|
||||
data__index_html + 12,
|
||||
sizeof(data__index_html) - 12,
|
||||
1,
|
||||
}};
|
||||
|
||||
#define FS_ROOT file__index_html
|
||||
#define FS_NUMFILES 3
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_FSDATA_H
|
||||
#define LWIP_FSDATA_H
|
||||
|
||||
#include "lwip/apps/httpd_opts.h"
|
||||
#include "lwip/apps/fs.h"
|
||||
|
||||
struct fsdata_file {
|
||||
const struct fsdata_file *next;
|
||||
const unsigned char *name;
|
||||
const unsigned char *data;
|
||||
int len;
|
||||
u8_t flags;
|
||||
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||
u16_t chksum_count;
|
||||
const struct fsdata_chksum *chksum;
|
||||
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||
};
|
||||
|
||||
#endif /* LWIP_FSDATA_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,114 @@
|
||||
#ifndef LWIP_HTTPD_STRUCTS_H
|
||||
#define LWIP_HTTPD_STRUCTS_H
|
||||
|
||||
#include "lwip/apps/httpd.h"
|
||||
|
||||
#if LWIP_HTTPD_DYNAMIC_HEADERS
|
||||
/** This struct is used for a list of HTTP header strings for various
|
||||
* filename extensions. */
|
||||
typedef struct
|
||||
{
|
||||
const char *extension;
|
||||
const char *content_type;
|
||||
} tHTTPHeader;
|
||||
|
||||
/** A list of strings used in HTTP headers (see RFC 1945 HTTP/1.0 and
|
||||
* RFC 2616 HTTP/1.1 for header field definitions) */
|
||||
static const char * const g_psHTTPHeaderStrings[] =
|
||||
{
|
||||
"HTTP/1.0 200 OK\r\n",
|
||||
"HTTP/1.0 404 File not found\r\n",
|
||||
"HTTP/1.0 400 Bad Request\r\n",
|
||||
"HTTP/1.0 501 Not Implemented\r\n",
|
||||
"HTTP/1.1 200 OK\r\n",
|
||||
"HTTP/1.1 404 File not found\r\n",
|
||||
"HTTP/1.1 400 Bad Request\r\n",
|
||||
"HTTP/1.1 501 Not Implemented\r\n",
|
||||
"Content-Length: ",
|
||||
"Connection: Close\r\n",
|
||||
"Connection: keep-alive\r\n",
|
||||
"Connection: keep-alive\r\nContent-Length: ",
|
||||
"Server: "HTTPD_SERVER_AGENT"\r\n",
|
||||
"\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||
,"Connection: keep-alive\r\nContent-Length: 77\r\n\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Indexes into the g_psHTTPHeaderStrings array */
|
||||
#define HTTP_HDR_OK 0 /* 200 OK */
|
||||
#define HTTP_HDR_NOT_FOUND 1 /* 404 File not found */
|
||||
#define HTTP_HDR_BAD_REQUEST 2 /* 400 Bad request */
|
||||
#define HTTP_HDR_NOT_IMPL 3 /* 501 Not Implemented */
|
||||
#define HTTP_HDR_OK_11 4 /* 200 OK */
|
||||
#define HTTP_HDR_NOT_FOUND_11 5 /* 404 File not found */
|
||||
#define HTTP_HDR_BAD_REQUEST_11 6 /* 400 Bad request */
|
||||
#define HTTP_HDR_NOT_IMPL_11 7 /* 501 Not Implemented */
|
||||
#define HTTP_HDR_CONTENT_LENGTH 8 /* Content-Length: (HTTP 1.0)*/
|
||||
#define HTTP_HDR_CONN_CLOSE 9 /* Connection: Close (HTTP 1.1) */
|
||||
#define HTTP_HDR_CONN_KEEPALIVE 10 /* Connection: keep-alive (HTTP 1.1) */
|
||||
#define HTTP_HDR_KEEPALIVE_LEN 11 /* Connection: keep-alive + Content-Length: (HTTP 1.1)*/
|
||||
#define HTTP_HDR_SERVER 12 /* Server: HTTPD_SERVER_AGENT */
|
||||
#define DEFAULT_404_HTML 13 /* default 404 body */
|
||||
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||
#define DEFAULT_404_HTML_PERSISTENT 14 /* default 404 body, but including Connection: keep-alive */
|
||||
#endif
|
||||
|
||||
|
||||
#define HTTP_HDR_HTML "Content-type: text/html\r\n\r\n"
|
||||
#define HTTP_HDR_SSI "Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n"
|
||||
#define HTTP_HDR_GIF "Content-type: image/gif\r\n\r\n"
|
||||
#define HTTP_HDR_PNG "Content-type: image/png\r\n\r\n"
|
||||
#define HTTP_HDR_JPG "Content-type: image/jpeg\r\n\r\n"
|
||||
#define HTTP_HDR_BMP "Content-type: image/bmp\r\n\r\n"
|
||||
#define HTTP_HDR_ICO "Content-type: image/x-icon\r\n\r\n"
|
||||
#define HTTP_HDR_APP "Content-type: application/octet-stream\r\n\r\n"
|
||||
#define HTTP_HDR_JS "Content-type: application/javascript\r\n\r\n"
|
||||
#define HTTP_HDR_RA "Content-type: application/javascript\r\n\r\n"
|
||||
#define HTTP_HDR_CSS "Content-type: text/css\r\n\r\n"
|
||||
#define HTTP_HDR_SWF "Content-type: application/x-shockwave-flash\r\n\r\n"
|
||||
#define HTTP_HDR_XML "Content-type: text/xml\r\n\r\n"
|
||||
#define HTTP_HDR_PDF "Content-type: application/pdf\r\n\r\n"
|
||||
#define HTTP_HDR_JSON "Content-type: application/json\r\n\r\n"
|
||||
|
||||
#define HTTP_HDR_DEFAULT_TYPE "Content-type: text/plain\r\n\r\n"
|
||||
|
||||
/** A list of extension-to-HTTP header strings (see outdated RFC 1700 MEDIA TYPES
|
||||
* and http://www.iana.org/assignments/media-types for registered content types
|
||||
* and subtypes) */
|
||||
static const tHTTPHeader g_psHTTPHeaders[] =
|
||||
{
|
||||
{ "html", HTTP_HDR_HTML},
|
||||
{ "htm", HTTP_HDR_HTML},
|
||||
{ "shtml",HTTP_HDR_SSI},
|
||||
{ "shtm", HTTP_HDR_SSI},
|
||||
{ "ssi", HTTP_HDR_SSI},
|
||||
{ "gif", HTTP_HDR_GIF},
|
||||
{ "png", HTTP_HDR_PNG},
|
||||
{ "jpg", HTTP_HDR_JPG},
|
||||
{ "bmp", HTTP_HDR_BMP},
|
||||
{ "ico", HTTP_HDR_ICO},
|
||||
{ "class",HTTP_HDR_APP},
|
||||
{ "cls", HTTP_HDR_APP},
|
||||
{ "js", HTTP_HDR_JS},
|
||||
{ "ram", HTTP_HDR_RA},
|
||||
{ "css", HTTP_HDR_CSS},
|
||||
{ "swf", HTTP_HDR_SWF},
|
||||
{ "xml", HTTP_HDR_XML},
|
||||
{ "xsl", HTTP_HDR_XML},
|
||||
{ "pdf", HTTP_HDR_PDF},
|
||||
{ "json", HTTP_HDR_JSON}
|
||||
};
|
||||
|
||||
#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader))
|
||||
|
||||
#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
|
||||
|
||||
#if LWIP_HTTPD_SSI
|
||||
static const char * const g_pcSSIExtensions[] = {
|
||||
".shtml", ".shtm", ".ssi", ".xml"
|
||||
};
|
||||
#define NUM_SHTML_EXTENSIONS (sizeof(g_pcSSIExtensions) / sizeof(const char *))
|
||||
#endif /* LWIP_HTTPD_SSI */
|
||||
|
||||
#endif /* LWIP_HTTPD_STRUCTS_H */
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
open(OUTPUT, "> fsdata.c");
|
||||
|
||||
chdir("fs");
|
||||
open(FILES, "find . -type f |");
|
||||
|
||||
while($file = <FILES>) {
|
||||
|
||||
# Do not include files in CVS directories nor backup files.
|
||||
if($file =~ /(CVS|~)/) {
|
||||
next;
|
||||
}
|
||||
|
||||
chop($file);
|
||||
|
||||
open(HEADER, "> /tmp/header") || die $!;
|
||||
if($file =~ /404/) {
|
||||
print(HEADER "HTTP/1.0 404 File not found\r\n");
|
||||
} else {
|
||||
print(HEADER "HTTP/1.0 200 OK\r\n");
|
||||
}
|
||||
print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
|
||||
if($file =~ /\.html$/) {
|
||||
print(HEADER "Content-type: text/html\r\n");
|
||||
} elsif($file =~ /\.gif$/) {
|
||||
print(HEADER "Content-type: image/gif\r\n");
|
||||
} elsif($file =~ /\.png$/) {
|
||||
print(HEADER "Content-type: image/png\r\n");
|
||||
} elsif($file =~ /\.jpg$/) {
|
||||
print(HEADER "Content-type: image/jpeg\r\n");
|
||||
} elsif($file =~ /\.class$/) {
|
||||
print(HEADER "Content-type: application/octet-stream\r\n");
|
||||
} elsif($file =~ /\.ram$/) {
|
||||
print(HEADER "Content-type: audio/x-pn-realaudio\r\n");
|
||||
} else {
|
||||
print(HEADER "Content-type: text/plain\r\n");
|
||||
}
|
||||
print(HEADER "\r\n");
|
||||
close(HEADER);
|
||||
|
||||
unless($file =~ /\.plain$/ || $file =~ /cgi/) {
|
||||
system("cat /tmp/header $file > /tmp/file");
|
||||
} else {
|
||||
system("cp $file /tmp/file");
|
||||
}
|
||||
|
||||
open(FILE, "/tmp/file");
|
||||
unlink("/tmp/file");
|
||||
unlink("/tmp/header");
|
||||
|
||||
$file =~ s/\.//;
|
||||
$fvar = $file;
|
||||
$fvar =~ s-/-_-g;
|
||||
$fvar =~ s-\.-_-g;
|
||||
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
|
||||
print(OUTPUT "\t/* $file */\n\t");
|
||||
for($j = 0; $j < length($file); $j++) {
|
||||
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
|
||||
}
|
||||
printf(OUTPUT "0,\n");
|
||||
|
||||
|
||||
$i = 0;
|
||||
while(read(FILE, $data, 1)) {
|
||||
if($i == 0) {
|
||||
print(OUTPUT "\t");
|
||||
}
|
||||
printf(OUTPUT "%#02x, ", unpack("C", $data));
|
||||
$i++;
|
||||
if($i == 10) {
|
||||
print(OUTPUT "\n");
|
||||
$i = 0;
|
||||
}
|
||||
}
|
||||
print(OUTPUT "};\n\n");
|
||||
close(FILE);
|
||||
push(@fvars, $fvar);
|
||||
push(@files, $file);
|
||||
}
|
||||
|
||||
for($i = 0; $i < @fvars; $i++) {
|
||||
$file = $files[$i];
|
||||
$fvar = $fvars[$i];
|
||||
|
||||
if($i == 0) {
|
||||
$prevfile = "NULL";
|
||||
} else {
|
||||
$prevfile = "file" . $fvars[$i - 1];
|
||||
}
|
||||
print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
|
||||
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
|
||||
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
|
||||
}
|
||||
|
||||
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
|
||||
print(OUTPUT "#define FS_NUMFILES $i\n");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
This directory contains a script ('makefsdata') to create C code suitable for
|
||||
httpd for given html pages (or other files) in a directory.
|
||||
|
||||
There is also a plain C console application doing the same and extended a bit.
|
||||
|
||||
Usage: htmlgen [targetdir] [-s] [-i]s
|
||||
targetdir: relative or absolute path to files to convert
|
||||
switch -s: toggle processing of subdirectories (default is on)
|
||||
switch -e: exclude HTTP header from file (header is created at runtime, default is on)
|
||||
switch -11: include HTTP 1.1 header (1.0 is default)
|
||||
|
||||
if targetdir not specified, makefsdata will attempt to
|
||||
process files in subdirectory 'fs'.
|
||||
@@ -0,0 +1,661 @@
|
||||
/**
|
||||
* @file
|
||||
* lwIP iPerf server implementation
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup iperf Iperf server
|
||||
* @ingroup apps
|
||||
*
|
||||
* This is a simple performance measuring server to check your bandwith using
|
||||
* iPerf2 on a PC as client.
|
||||
* It is currently a minimal implementation providing an IPv4 TCP server only.
|
||||
*
|
||||
* @todo: implement UDP mode and IPv6
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Simon Goldschmidt
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Simon Goldschmidt
|
||||
*/
|
||||
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Currently, only TCP-over-IPv4 is implemented (does iperf support IPv6 anyway?) */
|
||||
#if LWIP_IPV4 && LWIP_TCP && LWIP_CALLBACK_API
|
||||
|
||||
/** Specify the idle timeout (in seconds) after that the test fails */
|
||||
#ifndef LWIPERF_TCP_MAX_IDLE_SEC
|
||||
#define LWIPERF_TCP_MAX_IDLE_SEC 10U
|
||||
#endif
|
||||
#if LWIPERF_TCP_MAX_IDLE_SEC > 255
|
||||
#error LWIPERF_TCP_MAX_IDLE_SEC must fit into an u8_t
|
||||
#endif
|
||||
|
||||
/* File internal memory allocation (struct lwiperf_*): this defaults to
|
||||
the heap */
|
||||
#ifndef LWIPERF_ALLOC
|
||||
#define LWIPERF_ALLOC(type) mem_malloc(sizeof(type))
|
||||
#define LWIPERF_FREE(type, item) mem_free(item)
|
||||
#endif
|
||||
|
||||
/** If this is 1, check that received data has the correct format */
|
||||
#ifndef LWIPERF_CHECK_RX_DATA
|
||||
#define LWIPERF_CHECK_RX_DATA 0
|
||||
#endif
|
||||
|
||||
/** This is the Iperf settings struct sent from the client */
|
||||
typedef struct _lwiperf_settings {
|
||||
#define LWIPERF_FLAGS_ANSWER_TEST 0x80000000
|
||||
#define LWIPERF_FLAGS_ANSWER_NOW 0x00000001
|
||||
u32_t flags;
|
||||
u32_t num_threads; /* unused for now */
|
||||
u32_t remote_port;
|
||||
u32_t buffer_len; /* unused for now */
|
||||
u32_t win_band; /* TCP window / UDP rate: unused for now */
|
||||
u32_t amount; /* pos. value: bytes?; neg. values: time (unit is 10ms: 1/100 second) */
|
||||
} lwiperf_settings_t;
|
||||
|
||||
/** Basic connection handle */
|
||||
struct _lwiperf_state_base;
|
||||
typedef struct _lwiperf_state_base lwiperf_state_base_t;
|
||||
struct _lwiperf_state_base {
|
||||
/* 1=tcp, 0=udp */
|
||||
u8_t tcp;
|
||||
/* 1=server, 0=client */
|
||||
u8_t server;
|
||||
lwiperf_state_base_t* next;
|
||||
lwiperf_state_base_t* related_server_state;
|
||||
};
|
||||
|
||||
/** Connection handle for a TCP iperf session */
|
||||
typedef struct _lwiperf_state_tcp {
|
||||
lwiperf_state_base_t base;
|
||||
struct tcp_pcb* server_pcb;
|
||||
struct tcp_pcb* conn_pcb;
|
||||
u32_t time_started;
|
||||
lwiperf_report_fn report_fn;
|
||||
void* report_arg;
|
||||
u8_t poll_count;
|
||||
u8_t next_num;
|
||||
u32_t bytes_transferred;
|
||||
lwiperf_settings_t settings;
|
||||
u8_t have_settings_buf;
|
||||
} lwiperf_state_tcp_t;
|
||||
|
||||
/** List of active iperf sessions */
|
||||
static lwiperf_state_base_t* lwiperf_all_connections;
|
||||
/** A const buffer to send from: we want to measure sending, not copying! */
|
||||
static const u8_t lwiperf_txbuf_const[1600] = {
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
'0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9',
|
||||
};
|
||||
|
||||
static err_t lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb);
|
||||
static void lwiperf_tcp_err(void *arg, err_t err);
|
||||
|
||||
/** Add an iperf session to the 'active' list */
|
||||
static void
|
||||
lwiperf_list_add(lwiperf_state_base_t* item)
|
||||
{
|
||||
if (lwiperf_all_connections == NULL) {
|
||||
lwiperf_all_connections = item;
|
||||
} else {
|
||||
item = lwiperf_all_connections;
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove an iperf session from the 'active' list */
|
||||
static void
|
||||
lwiperf_list_remove(lwiperf_state_base_t* item)
|
||||
{
|
||||
lwiperf_state_base_t* prev = NULL;
|
||||
lwiperf_state_base_t* iter;
|
||||
for (iter = lwiperf_all_connections; iter != NULL; prev = iter, iter = iter->next) {
|
||||
if (iter == item) {
|
||||
if (prev == NULL) {
|
||||
lwiperf_all_connections = iter->next;
|
||||
} else {
|
||||
prev->next = item;
|
||||
}
|
||||
/* @debug: ensure this item is listed only once */
|
||||
for (iter = iter->next; iter != NULL; iter = iter->next) {
|
||||
LWIP_ASSERT("duplicate entry", iter != item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Call the report function of an iperf tcp session */
|
||||
static void
|
||||
lwip_tcp_conn_report(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type)
|
||||
{
|
||||
if ((conn != NULL) && (conn->report_fn != NULL)) {
|
||||
u32_t now, duration_ms, bandwidth_kbitpsec;
|
||||
now = sys_now();
|
||||
duration_ms = now - conn->time_started;
|
||||
if (duration_ms == 0) {
|
||||
bandwidth_kbitpsec = 0;
|
||||
} else {
|
||||
bandwidth_kbitpsec = (conn->bytes_transferred / duration_ms) * 8U;
|
||||
}
|
||||
conn->report_fn(conn->report_arg, report_type,
|
||||
&conn->conn_pcb->local_ip, conn->conn_pcb->local_port,
|
||||
&conn->conn_pcb->remote_ip, conn->conn_pcb->remote_port,
|
||||
conn->bytes_transferred, duration_ms, bandwidth_kbitpsec);
|
||||
}
|
||||
}
|
||||
|
||||
/** Close an iperf tcp session */
|
||||
static void
|
||||
lwiperf_tcp_close(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type)
|
||||
{
|
||||
err_t err;
|
||||
|
||||
lwip_tcp_conn_report(conn, report_type);
|
||||
lwiperf_list_remove(&conn->base);
|
||||
if (conn->conn_pcb != NULL) {
|
||||
tcp_arg(conn->conn_pcb, NULL);
|
||||
tcp_poll(conn->conn_pcb, NULL, 0);
|
||||
tcp_sent(conn->conn_pcb, NULL);
|
||||
tcp_recv(conn->conn_pcb, NULL);
|
||||
tcp_err(conn->conn_pcb, NULL);
|
||||
err = tcp_close(conn->conn_pcb);
|
||||
if (err != ERR_OK) {
|
||||
/* don't want to wait for free memory here... */
|
||||
tcp_abort(conn->conn_pcb);
|
||||
}
|
||||
} else {
|
||||
/* no conn pcb, this is the server pcb */
|
||||
err = tcp_close(conn->server_pcb);
|
||||
LWIP_ASSERT("error", err != ERR_OK);
|
||||
}
|
||||
LWIPERF_FREE(lwiperf_state_tcp_t, conn);
|
||||
}
|
||||
|
||||
/** Try to send more data on an iperf tcp session */
|
||||
static err_t
|
||||
lwiperf_tcp_client_send_more(lwiperf_state_tcp_t* conn)
|
||||
{
|
||||
int send_more;
|
||||
err_t err;
|
||||
u16_t txlen;
|
||||
u16_t txlen_max;
|
||||
void* txptr;
|
||||
u8_t apiflags;
|
||||
|
||||
LWIP_ASSERT("conn invalid", (conn != NULL) && conn->base.tcp && (conn->base.server == 0));
|
||||
|
||||
do {
|
||||
send_more = 0;
|
||||
if (conn->settings.amount & PP_HTONL(0x80000000)) {
|
||||
/* this session is time-limited */
|
||||
u32_t now = sys_now();
|
||||
u32_t diff_ms = now - conn->time_started;
|
||||
u32_t time = (u32_t)-(s32_t)lwip_htonl(conn->settings.amount);
|
||||
u32_t time_ms = time * 10;
|
||||
if (diff_ms >= time_ms) {
|
||||
/* time specified by the client is over -> close the connection */
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
|
||||
return ERR_OK;
|
||||
}
|
||||
} else {
|
||||
/* this session is byte-limited */
|
||||
u32_t amount_bytes = lwip_htonl(conn->settings.amount);
|
||||
/* @todo: this can send up to 1*MSS more than requested... */
|
||||
if (amount_bytes >= conn->bytes_transferred) {
|
||||
/* all requested bytes transferred -> close the connection */
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT);
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->bytes_transferred < 24) {
|
||||
/* transmit the settings a first time */
|
||||
txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred];
|
||||
txlen_max = (u16_t)(24 - conn->bytes_transferred);
|
||||
apiflags = TCP_WRITE_FLAG_COPY;
|
||||
} else if (conn->bytes_transferred < 48) {
|
||||
/* transmit the settings a second time */
|
||||
txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred - 24];
|
||||
txlen_max = (u16_t)(48 - conn->bytes_transferred);
|
||||
apiflags = TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE;
|
||||
send_more = 1;
|
||||
} else {
|
||||
/* transmit data */
|
||||
/* @todo: every x bytes, transmit the settings again */
|
||||
txptr = LWIP_CONST_CAST(void*, &lwiperf_txbuf_const[conn->bytes_transferred % 10]);
|
||||
txlen_max = TCP_MSS;
|
||||
if (conn->bytes_transferred == 48) { /* @todo: fix this for intermediate settings, too */
|
||||
txlen_max = TCP_MSS - 24;
|
||||
}
|
||||
apiflags = 0; /* no copying needed */
|
||||
send_more = 1;
|
||||
}
|
||||
txlen = txlen_max;
|
||||
do {
|
||||
err = tcp_write(conn->conn_pcb, txptr, txlen, apiflags);
|
||||
if (err == ERR_MEM) {
|
||||
txlen /= 2;
|
||||
}
|
||||
} while ((err == ERR_MEM) && (txlen >= (TCP_MSS/2)));
|
||||
|
||||
if (err == ERR_OK) {
|
||||
conn->bytes_transferred += txlen;
|
||||
} else {
|
||||
send_more = 0;
|
||||
}
|
||||
} while(send_more);
|
||||
|
||||
tcp_output(conn->conn_pcb);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/** TCP sent callback, try to send more data */
|
||||
static err_t
|
||||
lwiperf_tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
|
||||
{
|
||||
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||
/* @todo: check 'len' (e.g. to time ACK of all data)? for now, we just send more... */
|
||||
LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
|
||||
LWIP_UNUSED_ARG(tpcb);
|
||||
LWIP_UNUSED_ARG(len);
|
||||
|
||||
conn->poll_count = 0;
|
||||
|
||||
return lwiperf_tcp_client_send_more(conn);
|
||||
}
|
||||
|
||||
/** TCP connected callback (active connection), send data now */
|
||||
static err_t
|
||||
lwiperf_tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
|
||||
{
|
||||
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||
LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb);
|
||||
LWIP_UNUSED_ARG(tpcb);
|
||||
if (err != ERR_OK) {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
|
||||
return ERR_OK;
|
||||
}
|
||||
conn->poll_count = 0;
|
||||
conn->time_started = sys_now();
|
||||
return lwiperf_tcp_client_send_more(conn);
|
||||
}
|
||||
|
||||
/** Start TCP connection back to the client (either parallel or after the
|
||||
* receive test has finished.
|
||||
*/
|
||||
static err_t
|
||||
lwiperf_tx_start(lwiperf_state_tcp_t* conn)
|
||||
{
|
||||
err_t err;
|
||||
lwiperf_state_tcp_t* client_conn;
|
||||
struct tcp_pcb* newpcb;
|
||||
ip_addr_t remote_addr;
|
||||
u16_t remote_port;
|
||||
|
||||
client_conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t);
|
||||
if (client_conn == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
newpcb = tcp_new();
|
||||
if (newpcb == NULL) {
|
||||
LWIPERF_FREE(lwiperf_state_tcp_t, client_conn);
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
MEMCPY(client_conn, conn, sizeof(lwiperf_state_tcp_t));
|
||||
client_conn->base.server = 0;
|
||||
client_conn->server_pcb = NULL;
|
||||
client_conn->conn_pcb = newpcb;
|
||||
client_conn->time_started = sys_now(); /* @todo: set this again on 'connected' */
|
||||
client_conn->poll_count = 0;
|
||||
client_conn->next_num = 4; /* initial nr is '4' since the header has 24 byte */
|
||||
client_conn->bytes_transferred = 0;
|
||||
client_conn->settings.flags = 0; /* prevent the remote side starting back as client again */
|
||||
|
||||
tcp_arg(newpcb, client_conn);
|
||||
tcp_sent(newpcb, lwiperf_tcp_client_sent);
|
||||
tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
|
||||
tcp_err(newpcb, lwiperf_tcp_err);
|
||||
|
||||
ip_addr_copy(remote_addr, conn->conn_pcb->remote_ip);
|
||||
remote_port = (u16_t)lwip_htonl(client_conn->settings.remote_port);
|
||||
|
||||
err = tcp_connect(newpcb, &remote_addr, remote_port, lwiperf_tcp_client_connected);
|
||||
if (err != ERR_OK) {
|
||||
lwiperf_tcp_close(client_conn, LWIPERF_TCP_ABORTED_LOCAL);
|
||||
return err;
|
||||
}
|
||||
lwiperf_list_add(&client_conn->base);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/** Receive data on an iperf tcp session */
|
||||
static err_t
|
||||
lwiperf_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
|
||||
{
|
||||
u8_t tmp;
|
||||
u16_t tot_len;
|
||||
u32_t packet_idx;
|
||||
struct pbuf* q;
|
||||
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||
|
||||
LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
|
||||
LWIP_UNUSED_ARG(tpcb);
|
||||
|
||||
if (err != ERR_OK) {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
|
||||
return ERR_OK;
|
||||
}
|
||||
if (p == NULL) {
|
||||
/* connection closed -> test done */
|
||||
if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) ==
|
||||
PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) {
|
||||
/* client requested transmission after end of test */
|
||||
lwiperf_tx_start(conn);
|
||||
}
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_SERVER);
|
||||
return ERR_OK;
|
||||
}
|
||||
tot_len = p->tot_len;
|
||||
|
||||
conn->poll_count = 0;
|
||||
|
||||
if ((!conn->have_settings_buf) || ((conn->bytes_transferred -24) % (1024*128) == 0)) {
|
||||
/* wait for 24-byte header */
|
||||
if (p->tot_len < sizeof(lwiperf_settings_t)) {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
|
||||
pbuf_free(p);
|
||||
return ERR_VAL;
|
||||
}
|
||||
if (!conn->have_settings_buf) {
|
||||
if (pbuf_copy_partial(p, &conn->settings, sizeof(lwiperf_settings_t), 0) != sizeof(lwiperf_settings_t)) {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
|
||||
pbuf_free(p);
|
||||
return ERR_VAL;
|
||||
}
|
||||
conn->have_settings_buf = 1;
|
||||
if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) ==
|
||||
PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) {
|
||||
/* client requested parallel transmission test */
|
||||
err_t err2 = lwiperf_tx_start(conn);
|
||||
if (err2 != ERR_OK) {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_TXERROR);
|
||||
pbuf_free(p);
|
||||
return err2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pbuf_memcmp(p, 0, &conn->settings, sizeof(lwiperf_settings_t)) != 0) {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
|
||||
pbuf_free(p);
|
||||
return ERR_VAL;
|
||||
}
|
||||
}
|
||||
conn->bytes_transferred += sizeof(lwiperf_settings_t);
|
||||
if (conn->bytes_transferred <= 24) {
|
||||
conn->time_started = sys_now();
|
||||
tcp_recved(tpcb, p->tot_len);
|
||||
pbuf_free(p);
|
||||
return ERR_OK;
|
||||
}
|
||||
conn->next_num = 4; /* 24 bytes received... */
|
||||
tmp = pbuf_header(p, -24);
|
||||
LWIP_ASSERT("pbuf_header failed", tmp == 0);
|
||||
}
|
||||
|
||||
packet_idx = 0;
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
#if LWIPERF_CHECK_RX_DATA
|
||||
const u8_t* payload = (const u8_t*)q->payload;
|
||||
u16_t i;
|
||||
for (i = 0; i < q->len; i++) {
|
||||
u8_t val = payload[i];
|
||||
u8_t num = val - '0';
|
||||
if (num == conn->next_num) {
|
||||
conn->next_num++;
|
||||
if (conn->next_num == 10) {
|
||||
conn->next_num = 0;
|
||||
}
|
||||
} else {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR);
|
||||
pbuf_free(p);
|
||||
return ERR_VAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
packet_idx += q->len;
|
||||
}
|
||||
LWIP_ASSERT("count mismatch", packet_idx == p->tot_len);
|
||||
conn->bytes_transferred += packet_idx;
|
||||
tcp_recved(tpcb, tot_len);
|
||||
pbuf_free(p);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/** Error callback, iperf tcp session aborted */
|
||||
static void
|
||||
lwiperf_tcp_err(void *arg, err_t err)
|
||||
{
|
||||
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||
LWIP_UNUSED_ARG(err);
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE);
|
||||
}
|
||||
|
||||
/** TCP poll callback, try to send more data */
|
||||
static err_t
|
||||
lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb)
|
||||
{
|
||||
lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg;
|
||||
LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb);
|
||||
LWIP_UNUSED_ARG(tpcb);
|
||||
if (++conn->poll_count >= LWIPERF_TCP_MAX_IDLE_SEC) {
|
||||
lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL);
|
||||
return ERR_OK; /* lwiperf_tcp_close frees conn */
|
||||
}
|
||||
|
||||
if (!conn->base.server) {
|
||||
lwiperf_tcp_client_send_more(conn);
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/** This is called when a new client connects for an iperf tcp session */
|
||||
static err_t
|
||||
lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||||
{
|
||||
lwiperf_state_tcp_t *s, *conn;
|
||||
if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
s = (lwiperf_state_tcp_t*)arg;
|
||||
conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t);
|
||||
if (conn == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
memset(conn, 0, sizeof(lwiperf_state_tcp_t));
|
||||
conn->base.tcp = 1;
|
||||
conn->base.server = 1;
|
||||
conn->base.related_server_state = &s->base;
|
||||
conn->server_pcb = s->server_pcb;
|
||||
conn->conn_pcb = newpcb;
|
||||
conn->time_started = sys_now();
|
||||
conn->report_fn = s->report_fn;
|
||||
conn->report_arg = s->report_arg;
|
||||
|
||||
/* setup the tcp rx connection */
|
||||
tcp_arg(newpcb, conn);
|
||||
tcp_recv(newpcb, lwiperf_tcp_recv);
|
||||
tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
|
||||
tcp_err(conn->conn_pcb, lwiperf_tcp_err);
|
||||
|
||||
lwiperf_list_add(&conn->base);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iperf
|
||||
* Start a TCP iperf server on the default TCP port (5001) and listen for
|
||||
* incoming connections from iperf clients.
|
||||
*
|
||||
* @returns a connection handle that can be used to abort the server
|
||||
* by calling @ref lwiperf_abort()
|
||||
*/
|
||||
void*
|
||||
lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg)
|
||||
{
|
||||
return lwiperf_start_tcp_server(IP_ADDR_ANY, LWIPERF_TCP_PORT_DEFAULT,
|
||||
report_fn, report_arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iperf
|
||||
* Start a TCP iperf server on a specific IP address and port and listen for
|
||||
* incoming connections from iperf clients.
|
||||
*
|
||||
* @returns a connection handle that can be used to abort the server
|
||||
* by calling @ref lwiperf_abort()
|
||||
*/
|
||||
void*
|
||||
lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port,
|
||||
lwiperf_report_fn report_fn, void* report_arg)
|
||||
{
|
||||
err_t err;
|
||||
struct tcp_pcb* pcb;
|
||||
lwiperf_state_tcp_t* s;
|
||||
|
||||
if (local_addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t);
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(lwiperf_state_tcp_t));
|
||||
s->base.tcp = 1;
|
||||
s->base.server = 1;
|
||||
s->report_fn = report_fn;
|
||||
s->report_arg = report_arg;
|
||||
|
||||
pcb = tcp_new();
|
||||
if (pcb != NULL) {
|
||||
err = tcp_bind(pcb, local_addr, local_port);
|
||||
if (err == ERR_OK) {
|
||||
s->server_pcb = tcp_listen_with_backlog(pcb, 1);
|
||||
}
|
||||
}
|
||||
if (s->server_pcb == NULL) {
|
||||
if (pcb != NULL) {
|
||||
tcp_close(pcb);
|
||||
}
|
||||
LWIPERF_FREE(lwiperf_state_tcp_t, s);
|
||||
return NULL;
|
||||
}
|
||||
pcb = NULL;
|
||||
|
||||
tcp_arg(s->server_pcb, s);
|
||||
tcp_accept(s->server_pcb, lwiperf_tcp_accept);
|
||||
|
||||
lwiperf_list_add(&s->base);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iperf
|
||||
* Abort an iperf session (handle returned by lwiperf_start_tcp_server*())
|
||||
*/
|
||||
void
|
||||
lwiperf_abort(void* lwiperf_session)
|
||||
{
|
||||
lwiperf_state_base_t* i, *dealloc, *last = NULL;
|
||||
|
||||
for (i = lwiperf_all_connections; i != NULL; ) {
|
||||
if ((i == lwiperf_session) || (i->related_server_state == lwiperf_session)) {
|
||||
dealloc = i;
|
||||
i = i->next;
|
||||
if (last != NULL) {
|
||||
last->next = i;
|
||||
}
|
||||
LWIPERF_FREE(lwiperf_state_tcp_t, dealloc); /* @todo: type? */
|
||||
} else {
|
||||
last = i;
|
||||
i = i->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LWIP_IPV4 && LWIP_TCP && LWIP_CALLBACK_API */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* @file
|
||||
* NetBIOS name service responder
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup netbiosns NETBIOS responder
|
||||
* @ingroup apps
|
||||
*
|
||||
* This is an example implementation of a NetBIOS name server.
|
||||
* It responds to name queries for a configurable name.
|
||||
* Name resolving is not supported.
|
||||
*
|
||||
* Note that the device doesn't broadcast it's own name so can't
|
||||
* detect duplicate names!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/apps/netbiosns.h"
|
||||
|
||||
#if LWIP_IPV4 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/netif.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/** default port number for "NetBIOS Name service */
|
||||
#define NETBIOS_PORT 137
|
||||
|
||||
/** size of a NetBIOS name */
|
||||
#define NETBIOS_NAME_LEN 16
|
||||
|
||||
/** The Time-To-Live for NetBIOS name responds (in seconds)
|
||||
* Default is 300000 seconds (3 days, 11 hours, 20 minutes) */
|
||||
#define NETBIOS_NAME_TTL 300000u
|
||||
|
||||
/** NetBIOS header flags */
|
||||
#define NETB_HFLAG_RESPONSE 0x8000U
|
||||
#define NETB_HFLAG_OPCODE 0x7800U
|
||||
#define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U
|
||||
#define NETB_HFLAG_AUTHORATIVE 0x0400U
|
||||
#define NETB_HFLAG_TRUNCATED 0x0200U
|
||||
#define NETB_HFLAG_RECURS_DESIRED 0x0100U
|
||||
#define NETB_HFLAG_RECURS_AVAILABLE 0x0080U
|
||||
#define NETB_HFLAG_BROADCAST 0x0010U
|
||||
#define NETB_HFLAG_REPLYCODE 0x0008U
|
||||
#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U
|
||||
|
||||
/** NetBIOS name flags */
|
||||
#define NETB_NFLAG_UNIQUE 0x8000U
|
||||
#define NETB_NFLAG_NODETYPE 0x6000U
|
||||
#define NETB_NFLAG_NODETYPE_HNODE 0x6000U
|
||||
#define NETB_NFLAG_NODETYPE_MNODE 0x4000U
|
||||
#define NETB_NFLAG_NODETYPE_PNODE 0x2000U
|
||||
#define NETB_NFLAG_NODETYPE_BNODE 0x0000U
|
||||
|
||||
/** NetBIOS message header */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct netbios_hdr {
|
||||
PACK_STRUCT_FIELD(u16_t trans_id);
|
||||
PACK_STRUCT_FIELD(u16_t flags);
|
||||
PACK_STRUCT_FIELD(u16_t questions);
|
||||
PACK_STRUCT_FIELD(u16_t answerRRs);
|
||||
PACK_STRUCT_FIELD(u16_t authorityRRs);
|
||||
PACK_STRUCT_FIELD(u16_t additionalRRs);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/** NetBIOS message name part */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct netbios_name_hdr {
|
||||
PACK_STRUCT_FLD_8(u8_t nametype);
|
||||
PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN*2)+1]);
|
||||
PACK_STRUCT_FIELD(u16_t type);
|
||||
PACK_STRUCT_FIELD(u16_t cls);
|
||||
PACK_STRUCT_FIELD(u32_t ttl);
|
||||
PACK_STRUCT_FIELD(u16_t datalen);
|
||||
PACK_STRUCT_FIELD(u16_t flags);
|
||||
PACK_STRUCT_FLD_S(ip4_addr_p_t addr);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/** NetBIOS message */
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct netbios_resp
|
||||
{
|
||||
struct netbios_hdr resp_hdr;
|
||||
struct netbios_name_hdr resp_name;
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
#ifdef NETBIOS_LWIP_NAME
|
||||
#define NETBIOS_LOCAL_NAME NETBIOS_LWIP_NAME
|
||||
#else
|
||||
static char netbiosns_local_name[NETBIOS_NAME_LEN];
|
||||
#define NETBIOS_LOCAL_NAME netbiosns_local_name
|
||||
#endif
|
||||
|
||||
struct udp_pcb *netbiosns_pcb;
|
||||
|
||||
/** Decode a NetBIOS name (from packet to string) */
|
||||
static int
|
||||
netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len)
|
||||
{
|
||||
char *pname;
|
||||
char cname;
|
||||
char cnbname;
|
||||
int idx = 0;
|
||||
|
||||
LWIP_UNUSED_ARG(name_dec_len);
|
||||
|
||||
/* Start decoding netbios name. */
|
||||
pname = name_enc;
|
||||
for (;;) {
|
||||
/* Every two characters of the first level-encoded name
|
||||
* turn into one character in the decoded name. */
|
||||
cname = *pname;
|
||||
if (cname == '\0')
|
||||
break; /* no more characters */
|
||||
if (cname == '.')
|
||||
break; /* scope ID follows */
|
||||
if (cname < 'A' || cname > 'Z') {
|
||||
/* Not legal. */
|
||||
return -1;
|
||||
}
|
||||
cname -= 'A';
|
||||
cnbname = cname << 4;
|
||||
pname++;
|
||||
|
||||
cname = *pname;
|
||||
if (cname == '\0' || cname == '.') {
|
||||
/* No more characters in the name - but we're in
|
||||
* the middle of a pair. Not legal. */
|
||||
return -1;
|
||||
}
|
||||
if (cname < 'A' || cname > 'Z') {
|
||||
/* Not legal. */
|
||||
return -1;
|
||||
}
|
||||
cname -= 'A';
|
||||
cnbname |= cname;
|
||||
pname++;
|
||||
|
||||
/* Do we have room to store the character? */
|
||||
if (idx < NETBIOS_NAME_LEN) {
|
||||
/* Yes - store the character. */
|
||||
name_dec[idx++] = (cnbname!=' '?cnbname:'\0');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 /* function currently unused */
|
||||
/** Encode a NetBIOS name (from string to packet) - currently unused because
|
||||
we don't ask for names. */
|
||||
static int
|
||||
netbiosns_name_encode(char *name_enc, char *name_dec, int name_dec_len)
|
||||
{
|
||||
char *pname;
|
||||
char cname;
|
||||
unsigned char ucname;
|
||||
int idx = 0;
|
||||
|
||||
/* Start encoding netbios name. */
|
||||
pname = name_enc;
|
||||
|
||||
for (;;) {
|
||||
/* Every two characters of the first level-encoded name
|
||||
* turn into one character in the decoded name. */
|
||||
cname = *pname;
|
||||
if (cname == '\0')
|
||||
break; /* no more characters */
|
||||
if (cname == '.')
|
||||
break; /* scope ID follows */
|
||||
if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) {
|
||||
/* Not legal. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Do we have room to store the character? */
|
||||
if (idx >= name_dec_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Yes - store the character. */
|
||||
ucname = cname;
|
||||
name_dec[idx++] = ('A'+((ucname>>4) & 0x0F));
|
||||
name_dec[idx++] = ('A'+( ucname & 0x0F));
|
||||
pname++;
|
||||
}
|
||||
|
||||
/* Fill with "space" coding */
|
||||
for (;idx < name_dec_len - 1;) {
|
||||
name_dec[idx++] = 'C';
|
||||
name_dec[idx++] = 'A';
|
||||
}
|
||||
|
||||
/* Terminate string */
|
||||
name_dec[idx] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/** NetBIOS Name service recv callback */
|
||||
static void
|
||||
netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||
{
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
|
||||
/* if packet is valid */
|
||||
if (p != NULL) {
|
||||
char netbios_name[NETBIOS_NAME_LEN+1];
|
||||
struct netbios_hdr* netbios_hdr = (struct netbios_hdr*)p->payload;
|
||||
struct netbios_name_hdr* netbios_name_hdr = (struct netbios_name_hdr*)(netbios_hdr+1);
|
||||
|
||||
/* we only answer if we got a default interface */
|
||||
if (netif_default != NULL) {
|
||||
/* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */
|
||||
/* if the packet is a NetBIOS name query question */
|
||||
if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) &&
|
||||
((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) &&
|
||||
(netbios_hdr->questions == PP_NTOHS(1))) {
|
||||
/* decode the NetBIOS name */
|
||||
netbiosns_name_decode((char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
|
||||
/* if the packet is for us */
|
||||
if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
|
||||
struct pbuf *q;
|
||||
struct netbios_resp *resp;
|
||||
|
||||
q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM);
|
||||
if (q != NULL) {
|
||||
resp = (struct netbios_resp*)q->payload;
|
||||
|
||||
/* prepare NetBIOS header response */
|
||||
resp->resp_hdr.trans_id = netbios_hdr->trans_id;
|
||||
resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE |
|
||||
NETB_HFLAG_OPCODE_NAME_QUERY |
|
||||
NETB_HFLAG_AUTHORATIVE |
|
||||
NETB_HFLAG_RECURS_DESIRED);
|
||||
resp->resp_hdr.questions = 0;
|
||||
resp->resp_hdr.answerRRs = PP_HTONS(1);
|
||||
resp->resp_hdr.authorityRRs = 0;
|
||||
resp->resp_hdr.additionalRRs = 0;
|
||||
|
||||
/* prepare NetBIOS header datas */
|
||||
MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname));
|
||||
resp->resp_name.nametype = netbios_name_hdr->nametype;
|
||||
resp->resp_name.type = netbios_name_hdr->type;
|
||||
resp->resp_name.cls = netbios_name_hdr->cls;
|
||||
resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL);
|
||||
resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr));
|
||||
resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE);
|
||||
ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default));
|
||||
|
||||
/* send the NetBIOS response */
|
||||
udp_sendto(upcb, q, addr, port);
|
||||
|
||||
/* free the "reference" pbuf */
|
||||
pbuf_free(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* free the pbuf */
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netbiosns
|
||||
* Init netbios responder
|
||||
*/
|
||||
void
|
||||
netbiosns_init(void)
|
||||
{
|
||||
#ifdef NETBIOS_LWIP_NAME
|
||||
LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN);
|
||||
#endif
|
||||
|
||||
netbiosns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||
if (netbiosns_pcb != NULL) {
|
||||
/* we have to be allowed to send broadcast packets! */
|
||||
ip_set_option(netbiosns_pcb, SOF_BROADCAST);
|
||||
udp_bind(netbiosns_pcb, IP_ANY_TYPE, NETBIOS_PORT);
|
||||
udp_recv(netbiosns_pcb, netbiosns_recv, netbiosns_pcb);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NETBIOS_LWIP_NAME
|
||||
/**
|
||||
* @ingroup netbiosns
|
||||
* Set netbios name. ATTENTION: the hostname must be less than 15 characters!
|
||||
*/
|
||||
void
|
||||
netbiosns_set_name(const char* hostname)
|
||||
{
|
||||
size_t copy_len = strlen(hostname);
|
||||
LWIP_ASSERT("NetBIOS name is too long!", copy_len < NETBIOS_NAME_LEN);
|
||||
if (copy_len >= NETBIOS_NAME_LEN) {
|
||||
copy_len = NETBIOS_NAME_LEN - 1;
|
||||
}
|
||||
MEMCPY(netbiosns_local_name, hostname, copy_len + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup netbiosns
|
||||
* Stop netbios responder
|
||||
*/
|
||||
void
|
||||
netbiosns_stop(void)
|
||||
{
|
||||
if (netbiosns_pcb != NULL) {
|
||||
udp_remove(netbiosns_pcb);
|
||||
netbiosns_pcb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LWIP_IPV4 && LWIP_UDP */
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CCodeGeneration</RootNamespace>
|
||||
<AssemblyName>CCodeGeneration</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CFile.cs" />
|
||||
<Compile Include="Code.cs" />
|
||||
<Compile Include="CodeContainerBase.cs" />
|
||||
<Compile Include="CodeElement.cs" />
|
||||
<Compile Include="Comment.cs" />
|
||||
<Compile Include="EmptyLine.cs" />
|
||||
<Compile Include="Function.cs" />
|
||||
<Compile Include="CGenerator.cs" />
|
||||
<Compile Include="IfThenElse.cs" />
|
||||
<Compile Include="PlainText.cs" />
|
||||
<Compile Include="Switch.cs" />
|
||||
<Compile Include="PP_If.cs" />
|
||||
<Compile Include="PP_Ifdef.cs" />
|
||||
<Compile Include="PP_Include.cs" />
|
||||
<Compile Include="FunctionDeclaration.cs" />
|
||||
<Compile Include="PP_Macro.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="VariableDeclaration.cs" />
|
||||
<Compile Include="VariablePrototype.cs" />
|
||||
<Compile Include="VariableType.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class CFile: CodeContainerBase
|
||||
{
|
||||
public CFile()
|
||||
{
|
||||
base.IncreaseLevel = false;
|
||||
}
|
||||
|
||||
public void Save(CGenerator generator)
|
||||
{
|
||||
if (generator == null)
|
||||
{
|
||||
throw new ArgumentNullException("generator");
|
||||
}
|
||||
|
||||
this.GenerateCode(0, generator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class CGenerator
|
||||
{
|
||||
public TextWriter OutputStream { get; private set; }
|
||||
public string File { get; private set; }
|
||||
public uint IndentCount { get; private set; }
|
||||
public string IndentChar { get; private set; }
|
||||
public string NewLine { get; private set; }
|
||||
|
||||
public CGenerator(System.IO.TextWriter outputStream, string file, uint indentCount, string indentChar, string newLine)
|
||||
{
|
||||
this.OutputStream = outputStream;
|
||||
this.File = file;
|
||||
this.IndentCount = indentCount;
|
||||
this.IndentChar = indentChar;
|
||||
this.NewLine = newLine;
|
||||
}
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.File))
|
||||
{
|
||||
return Path.GetFileName(this.File);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteSequence(string value, uint repetitions)
|
||||
{
|
||||
while (repetitions > 0)
|
||||
{
|
||||
this.OutputStream.Write(value);
|
||||
repetitions--;
|
||||
}
|
||||
}
|
||||
|
||||
public void IndentLine(int level)
|
||||
{
|
||||
while (level > 0)
|
||||
{
|
||||
WriteSequence(this.IndentChar, this.IndentCount);
|
||||
level--;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteNewLine()
|
||||
{
|
||||
this.OutputStream.Write(this.NewLine);
|
||||
}
|
||||
|
||||
public void WriteMultilineString(string value, int level = 0)
|
||||
{
|
||||
if (String.IsNullOrEmpty(value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// only \n and \r\n are recognized as linebreaks
|
||||
string[] lines = value.Split(new char[] { '\n' }, StringSplitOptions.None);
|
||||
|
||||
for (int l = 0; l < (lines.Length - 1); l++)
|
||||
{
|
||||
if (lines[l].EndsWith("\r"))
|
||||
{
|
||||
this.OutputStream.Write(lines[l].Substring(0, lines[l].Length-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.OutputStream.Write(lines[l]);
|
||||
}
|
||||
|
||||
this.WriteNewLine();
|
||||
this.IndentLine(level);
|
||||
}
|
||||
|
||||
this.OutputStream.Write(lines[lines.Length - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class Code: CodeElement
|
||||
{
|
||||
public string Code_ { get; set; }
|
||||
|
||||
public Code()
|
||||
{
|
||||
}
|
||||
|
||||
public Code(string code)
|
||||
{
|
||||
this.Code_ = code;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
generator.WriteMultilineString(this.Code_, level);
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class CodeContainerBase: CodeElement
|
||||
{
|
||||
private readonly List<CodeElement> declarations = new List<CodeElement>();
|
||||
private readonly List<CodeElement> innerElements = new List<CodeElement>();
|
||||
private bool increaseLevel = true;
|
||||
|
||||
public List<CodeElement> Declarations
|
||||
{
|
||||
get { return this.declarations; }
|
||||
}
|
||||
|
||||
public List<CodeElement> InnerElements
|
||||
{
|
||||
get { return this.innerElements; }
|
||||
}
|
||||
|
||||
protected bool IncreaseLevel
|
||||
{
|
||||
get { return this.increaseLevel; }
|
||||
set { this.increaseLevel = value; }
|
||||
}
|
||||
|
||||
public void AddElements(IList<CodeElement> elements, params CodeElement[] spacerElements)
|
||||
{
|
||||
if (elements != null)
|
||||
{
|
||||
if ((spacerElements == null) || (spacerElements.Length == 0))
|
||||
{
|
||||
this.innerElements.AddRange(elements);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool spacerAdded = false;
|
||||
|
||||
foreach (CodeElement element in elements)
|
||||
{
|
||||
this.innerElements.Add(element);
|
||||
this.innerElements.AddRange(spacerElements);
|
||||
spacerAdded = true;
|
||||
}
|
||||
|
||||
if (spacerAdded)
|
||||
{
|
||||
// remove last spacer again
|
||||
this.innerElements.RemoveRange(this.innerElements.Count - spacerElements.Length, spacerElements.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CodeElement AddElement(CodeElement element)
|
||||
{
|
||||
if (element != null)
|
||||
{
|
||||
this.innerElements.Add(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public Code AddCode(string code)
|
||||
{
|
||||
return this.AddElement(new Code(code)) as Code;
|
||||
}
|
||||
|
||||
public Code AddCodeFormat(string codeFormat, params object[] args)
|
||||
{
|
||||
return this.AddElement(new Code(String.Format(codeFormat, args))) as Code;
|
||||
}
|
||||
|
||||
public CodeElement AddDeclaration(CodeElement declaration)
|
||||
{
|
||||
if (declaration != null)
|
||||
{
|
||||
this.declarations.Add(declaration);
|
||||
}
|
||||
|
||||
return declaration;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (this.increaseLevel)
|
||||
level++;
|
||||
|
||||
if (this.declarations.Count > 0)
|
||||
{
|
||||
foreach (CodeElement element in this.declarations)
|
||||
{
|
||||
element.GenerateCode(level, generator);
|
||||
}
|
||||
|
||||
EmptyLine.SingleLine.GenerateCode(level, generator);
|
||||
}
|
||||
|
||||
foreach (CodeElement element in this.innerElements)
|
||||
{
|
||||
element.GenerateCode(level, generator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class CodeElement
|
||||
{
|
||||
public virtual void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class Comment: CodeElement
|
||||
{
|
||||
public const string CommentStart = "/*";
|
||||
public const string CommentEnd = "*/";
|
||||
|
||||
public string Comment_ { get; set; }
|
||||
public bool SingleLine { get; set; }
|
||||
|
||||
public Comment()
|
||||
{
|
||||
}
|
||||
|
||||
public Comment(string comment, bool singleLine = false)
|
||||
{
|
||||
this.Comment_ = comment;
|
||||
this.SingleLine = singleLine;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write(CommentStart);
|
||||
|
||||
if (!this.SingleLine)
|
||||
{
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level);
|
||||
generator.WriteMultilineString(this.Comment_, level);
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level);
|
||||
}
|
||||
else
|
||||
{
|
||||
generator.OutputStream.Write(" " + Comment_ + " ");
|
||||
}
|
||||
|
||||
generator.OutputStream.Write(CommentEnd);
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class EmptyLine : CodeElement
|
||||
{
|
||||
public static readonly EmptyLine SingleLine = new EmptyLine();
|
||||
public static readonly EmptyLine TwoLines = new EmptyLine(2);
|
||||
public static readonly EmptyLine ThreeLines = new EmptyLine(3);
|
||||
|
||||
public uint Count { get; set; }
|
||||
|
||||
public EmptyLine()
|
||||
{
|
||||
this.Count = 1;
|
||||
}
|
||||
|
||||
public EmptyLine(uint count)
|
||||
{
|
||||
this.Count = count;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
uint c = this.Count;
|
||||
|
||||
while (c > 0)
|
||||
{
|
||||
generator.WriteNewLine();
|
||||
c--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class Function: CodeContainerBase
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool IsStatic { get; set; }
|
||||
|
||||
private readonly List<VariableType> parameter = new List<VariableType>();
|
||||
private VariableType returnType = VariableType.Void;
|
||||
|
||||
public Function()
|
||||
{
|
||||
}
|
||||
|
||||
public Function(string name, bool isStatic = false)
|
||||
{
|
||||
this.Name = name;
|
||||
this.IsStatic = isStatic;
|
||||
}
|
||||
|
||||
public List<VariableType> Parameter
|
||||
{
|
||||
get { return this.parameter; }
|
||||
}
|
||||
|
||||
public VariableType ReturnType
|
||||
{
|
||||
get { return this.returnType; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("ReturnValue");
|
||||
}
|
||||
this.returnType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static Function FromDeclaration(FunctionDeclaration decl)
|
||||
{
|
||||
Function result = new Function(decl.Name, decl.IsStatic);
|
||||
result.ReturnType = decl.ReturnType.Clone() as VariableType;
|
||||
|
||||
foreach (VariableType param in decl.Parameter)
|
||||
{
|
||||
result.parameter.Add(param.Clone() as VariableType);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
|
||||
if (this.IsStatic)
|
||||
{
|
||||
generator.OutputStream.Write("static ");
|
||||
}
|
||||
|
||||
this.returnType.GenerateCode(generator);
|
||||
generator.OutputStream.Write(" " + this.Name + "(");
|
||||
|
||||
if (this.Parameter.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < this.parameter.Count; i++)
|
||||
{
|
||||
this.parameter[i].GenerateCode(generator);
|
||||
|
||||
if (i < (this.parameter.Count - 1))
|
||||
{
|
||||
generator.OutputStream.Write(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
generator.OutputStream.Write("void");
|
||||
}
|
||||
|
||||
generator.OutputStream.Write(")");
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("{");
|
||||
generator.WriteNewLine();
|
||||
|
||||
base.GenerateCode(level, generator);
|
||||
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("}");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class FunctionDeclaration: CodeElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool IsStatic { get; set; }
|
||||
public bool IsExtern { get; set; }
|
||||
|
||||
private readonly List<VariableType> parameter = new List<VariableType>();
|
||||
private VariableType returnType = VariableType.Void;
|
||||
|
||||
public FunctionDeclaration()
|
||||
{
|
||||
}
|
||||
|
||||
public FunctionDeclaration(string name, bool isStatic = false, bool isExtern = false)
|
||||
{
|
||||
this.Name = name;
|
||||
this.IsStatic = isStatic;
|
||||
this.IsExtern = isExtern;
|
||||
}
|
||||
|
||||
public List<VariableType> Parameter
|
||||
{
|
||||
get { return this.parameter; }
|
||||
}
|
||||
|
||||
public VariableType ReturnType
|
||||
{
|
||||
get { return this.returnType; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("ReturnValue");
|
||||
}
|
||||
this.returnType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
|
||||
if (this.IsExtern)
|
||||
{
|
||||
generator.OutputStream.Write("extern ");
|
||||
}
|
||||
|
||||
if (this.IsStatic)
|
||||
{
|
||||
generator.OutputStream.Write("static ");
|
||||
}
|
||||
|
||||
this.returnType.GenerateCode(generator);
|
||||
generator.OutputStream.Write(" " + this.Name + "(");
|
||||
|
||||
if (this.Parameter.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < this.parameter.Count; i++)
|
||||
{
|
||||
this.parameter[i].GenerateCode(generator);
|
||||
|
||||
if (i < (this.parameter.Count - 1))
|
||||
{
|
||||
generator.OutputStream.Write(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
generator.OutputStream.Write("void");
|
||||
}
|
||||
|
||||
generator.OutputStream.Write(");");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class ElseIf : CodeContainerBase
|
||||
{
|
||||
public string Condition { get; set; }
|
||||
|
||||
public ElseIf()
|
||||
{
|
||||
}
|
||||
|
||||
public ElseIf(string condition)
|
||||
{
|
||||
this.Condition = condition;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.Condition))
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write(String.Format("else if ({0})", this.Condition));
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("{");
|
||||
generator.WriteNewLine();
|
||||
|
||||
base.GenerateCode(level, generator);
|
||||
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("}");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IfThenElse: CodeContainerBase
|
||||
{
|
||||
public string Condition { get; set; }
|
||||
|
||||
private List<ElseIf> elseIf = new List<ElseIf>();
|
||||
private CodeContainerBase else_ = new CodeContainerBase();
|
||||
|
||||
public IfThenElse()
|
||||
{
|
||||
}
|
||||
|
||||
public IfThenElse(string condition)
|
||||
{
|
||||
this.Condition = condition;
|
||||
}
|
||||
|
||||
public List<ElseIf> ElseIf
|
||||
{
|
||||
get { return this.elseIf; }
|
||||
}
|
||||
|
||||
public CodeContainerBase Else
|
||||
{
|
||||
get { return this.else_; }
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.Condition))
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write(String.Format("if ({0})", this.Condition));
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("{");
|
||||
generator.WriteNewLine();
|
||||
|
||||
base.GenerateCode(level, generator);
|
||||
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("}");
|
||||
generator.WriteNewLine();
|
||||
|
||||
foreach (ElseIf elif in this.elseIf)
|
||||
{
|
||||
elif.GenerateCode(level, generator);
|
||||
}
|
||||
|
||||
if (this.else_.InnerElements.Count > 0)
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("else");
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("{");
|
||||
generator.WriteNewLine();
|
||||
|
||||
this.else_.GenerateCode(level, generator);
|
||||
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("}");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class PP_If: CodeContainerBase
|
||||
{
|
||||
public string Condition { get; set; }
|
||||
|
||||
public PP_If()
|
||||
{
|
||||
base.IncreaseLevel = false;
|
||||
}
|
||||
|
||||
public PP_If(string condition)
|
||||
: this()
|
||||
{
|
||||
this.Condition = condition;
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.Condition))
|
||||
{
|
||||
generator.OutputStream.Write("#if " + this.Condition);
|
||||
generator.WriteNewLine();
|
||||
|
||||
base.GenerateCode(level, generator);
|
||||
|
||||
generator.OutputStream.Write("#endif /* " + this.Condition + " */");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class PP_Ifdef: CodeContainerBase
|
||||
{
|
||||
public string Macro { get; set; }
|
||||
public bool Inverted { get; set; }
|
||||
|
||||
public PP_Ifdef()
|
||||
{
|
||||
base.IncreaseLevel = false;
|
||||
}
|
||||
|
||||
public PP_Ifdef(string macro, bool inverted = false)
|
||||
: this()
|
||||
{
|
||||
this.Macro = macro;
|
||||
this.Inverted = inverted;
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.Macro))
|
||||
{
|
||||
if (this.Inverted)
|
||||
{
|
||||
generator.OutputStream.Write("#ifndef " + this.Macro);
|
||||
}
|
||||
else
|
||||
{
|
||||
generator.OutputStream.Write("#ifdef " + this.Macro);
|
||||
}
|
||||
generator.WriteNewLine();
|
||||
|
||||
base.GenerateCode(level, generator);
|
||||
|
||||
generator.OutputStream.Write("#endif /* " + this.Macro + " */");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class PP_Include : CodeElement
|
||||
{
|
||||
public string File { get; set; }
|
||||
public bool IsLocal { get; set; }
|
||||
|
||||
public PP_Include()
|
||||
{
|
||||
this.IsLocal = true;
|
||||
}
|
||||
|
||||
public PP_Include(string file, bool isLocal = true)
|
||||
{
|
||||
this.File = file;
|
||||
this.IsLocal = isLocal;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.File))
|
||||
{
|
||||
// includes are never indented
|
||||
if (this.IsLocal)
|
||||
{
|
||||
generator.OutputStream.Write("#include \"" + this.File + "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
generator.OutputStream.Write("#include <" + this.File + ">");
|
||||
}
|
||||
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class PP_Macro: CodeElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
|
||||
public PP_Macro()
|
||||
{
|
||||
}
|
||||
|
||||
public PP_Macro(string name, string value)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
// macros are not indented at all
|
||||
generator.OutputStream.Write("#define " + this.Name + " ");
|
||||
generator.WriteMultilineString(this.Value);
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class PlainText : CodeElement
|
||||
{
|
||||
public string Value { get; set; }
|
||||
|
||||
public PlainText(string value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
generator.WriteMultilineString(this.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die mit einer Assembly verknüpft sind.
|
||||
[assembly: AssemblyTitle("CCodeGeneration")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("CCodeGeneration")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("8f07a0fa-86f4-48a0-97c7-f94fc5c3f103")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class SwitchCase : CodeContainerBase
|
||||
{
|
||||
public string Value { get; set; }
|
||||
|
||||
public SwitchCase()
|
||||
{
|
||||
}
|
||||
|
||||
public SwitchCase(string value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public bool IsDefault
|
||||
{
|
||||
get { return (this.Value.ToLowerInvariant() == "default"); }
|
||||
}
|
||||
|
||||
public static SwitchCase GenerateDefault()
|
||||
{
|
||||
return new SwitchCase("default");
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.Value))
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
if (this.IsDefault)
|
||||
{
|
||||
generator.OutputStream.Write("default:");
|
||||
}
|
||||
else
|
||||
{
|
||||
generator.OutputStream.Write(String.Format("case {0}:", this.Value));
|
||||
}
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level + 1);
|
||||
generator.OutputStream.Write("{");
|
||||
generator.WriteNewLine();
|
||||
|
||||
base.GenerateCode(level + 1, generator);
|
||||
|
||||
generator.IndentLine(level + 1);
|
||||
generator.OutputStream.Write("}");
|
||||
generator.WriteNewLine();
|
||||
|
||||
generator.IndentLine(level + 1);
|
||||
generator.OutputStream.Write("break;");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Switch: CodeElement
|
||||
{
|
||||
public string SwitchVar { get; set; }
|
||||
|
||||
private List<SwitchCase> switches = new List<SwitchCase>();
|
||||
|
||||
public Switch()
|
||||
{
|
||||
}
|
||||
|
||||
public Switch(string switchVar)
|
||||
{
|
||||
this.SwitchVar = switchVar;
|
||||
}
|
||||
|
||||
public List<SwitchCase> Switches
|
||||
{
|
||||
get { return this.switches; }
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.SwitchVar))
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write(String.Format("switch ({0})", this.SwitchVar));
|
||||
generator.WriteNewLine();
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("{");
|
||||
generator.WriteNewLine();
|
||||
|
||||
SwitchCase defaultCase = null; // generate 'default' always as last case
|
||||
foreach (SwitchCase switchCase in this.switches)
|
||||
{
|
||||
if (switchCase.IsDefault)
|
||||
{
|
||||
defaultCase = switchCase;
|
||||
}
|
||||
else
|
||||
{
|
||||
switchCase.GenerateCode(level + 1, generator);
|
||||
}
|
||||
}
|
||||
if (defaultCase != null)
|
||||
{
|
||||
defaultCase.GenerateCode(level + 1, generator);
|
||||
}
|
||||
|
||||
generator.IndentLine(level);
|
||||
generator.OutputStream.Write("}");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class VariableDeclaration : CodeElement
|
||||
{
|
||||
public VariableType Type { get; set; }
|
||||
public string InitialValue { get; set; }
|
||||
public bool IsStatic { get; set; }
|
||||
|
||||
public VariableDeclaration()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public VariableDeclaration(VariableType type, string initialValue = null, bool isStatic = false) :
|
||||
base()
|
||||
{
|
||||
this.Type = type;
|
||||
this.InitialValue = initialValue;
|
||||
this.IsStatic = isStatic;
|
||||
}
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (this.Type != null)
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
|
||||
if (this.IsStatic)
|
||||
{
|
||||
generator.OutputStream.Write("static ");
|
||||
}
|
||||
|
||||
// declare the variable
|
||||
this.Type.GenerateCode(generator);
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(this.InitialValue))
|
||||
{
|
||||
// add initialization value
|
||||
generator.OutputStream.Write(" = ");
|
||||
generator.WriteMultilineString(this.InitialValue, level);
|
||||
}
|
||||
|
||||
generator.OutputStream.Write(";");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public class VariablePrototype : CodeElement
|
||||
{
|
||||
public VariableType Type { get; set; }
|
||||
|
||||
public VariablePrototype()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public VariablePrototype(VariableType type) :
|
||||
base()
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public static VariablePrototype FromVariableDeclaration(VariableDeclaration declaration)
|
||||
{
|
||||
return new VariablePrototype(declaration.Type);
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateCode(int level, CGenerator generator)
|
||||
{
|
||||
if (this.Type != null)
|
||||
{
|
||||
generator.IndentLine(level);
|
||||
|
||||
generator.OutputStream.Write("extern ");
|
||||
|
||||
// declare the variable
|
||||
this.Type.GenerateCode(generator);
|
||||
|
||||
generator.OutputStream.Write(";");
|
||||
generator.WriteNewLine();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace CCodeGeneration
|
||||
{
|
||||
public enum ConstType
|
||||
{
|
||||
None,
|
||||
Value,
|
||||
Indirection,
|
||||
Both
|
||||
}
|
||||
|
||||
public class VariableType : ICloneable
|
||||
{
|
||||
public const string VoidString = "void";
|
||||
public static readonly VariableType Void = new VariableType(null, "void");
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string Indirection { get; set; }
|
||||
public ConstType Const { get; set; }
|
||||
public string ArraySpecifier { get; set; }
|
||||
|
||||
public VariableType()
|
||||
{
|
||||
}
|
||||
|
||||
public VariableType(string name, string type, string indirection = null, ConstType const_ = ConstType.None, string arraySpecifier = null)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Type = type;
|
||||
this.Indirection = indirection;
|
||||
this.Const = const_;
|
||||
this.ArraySpecifier = arraySpecifier;
|
||||
}
|
||||
|
||||
public void GenerateCode(CGenerator generator)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.Type))
|
||||
{
|
||||
generator.OutputStream.Write(this.ToString().Trim());
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(this.Type))
|
||||
{
|
||||
StringBuilder vt = new StringBuilder();
|
||||
|
||||
if ((this.Const == ConstType.Value) || (this.Const == ConstType.Both))
|
||||
{
|
||||
vt.Append("const ");
|
||||
}
|
||||
|
||||
vt.Append(this.Type);
|
||||
vt.Append(" ");
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(this.Indirection))
|
||||
{
|
||||
vt.Append(this.Indirection);
|
||||
}
|
||||
|
||||
if ((this.Const == ConstType.Indirection) || (this.Const == ConstType.Both))
|
||||
{
|
||||
vt.Append("const ");
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(this.Name))
|
||||
{
|
||||
vt.Append(this.Name);
|
||||
}
|
||||
|
||||
if (this.ArraySpecifier != null)
|
||||
{
|
||||
vt.Append("[");
|
||||
vt.Append(this.ArraySpecifier);
|
||||
vt.Append("]");
|
||||
}
|
||||
|
||||
return vt.ToString().Trim();
|
||||
}
|
||||
|
||||
return base.ToString();
|
||||
}
|
||||
|
||||
#region ICloneable Member
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
// we only have value types as members -> simply use .net base function
|
||||
return this.MemberwiseClone();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LwipMibCompiler", "LwipMibCompiler\LwipMibCompiler.csproj", "{C25D5640-D999-49BD-82E0-A1975296A91E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LwipSnmpCodeGeneration", "LwipSnmpCodeGeneration\LwipSnmpCodeGeneration.csproj", "{AABCAB90-1540-45D4-A159-14831A54E9A3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCodeGeneration", "CCodeGeneration\CCodeGeneration.csproj", "{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpSnmpLib.Mib", "SharpSnmpLib\SharpSnmpLib.Mib.csproj", "{CBE20411-5DB7-487D-825D-7694267BB6F5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LwipMibViewer", "LwipMibViewer\LwipMibViewer.csproj", "{86CC0B65-7985-4017-A252-0A7A18DCAEF3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{86CC0B65-7985-4017-A252-0A7A18DCAEF3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AABCAB90-1540-45D4-A159-14831A54E9A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AABCAB90-1540-45D4-A159-14831A54E9A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AABCAB90-1540-45D4-A159-14831A54E9A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AABCAB90-1540-45D4-A159-14831A54E9A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C25D5640-D999-49BD-82E0-A1975296A91E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C25D5640-D999-49BD-82E0-A1975296A91E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C25D5640-D999-49BD-82E0-A1975296A91E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C25D5640-D999-49BD-82E0-A1975296A91E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CBE20411-5DB7-487D-825D-7694267BB6F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CBE20411-5DB7-487D-825D-7694267BB6F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CBE20411-5DB7-487D-825D-7694267BB6F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CBE20411-5DB7-487D-825D-7694267BB6F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = LwipMibViewer\LwipMibViewer.csproj
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{C25D5640-D999-49BD-82E0-A1975296A91E}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>LwipMibCompiler</RootNamespace>
|
||||
<AssemblyName>LwipMibCompiler</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CCodeGeneration\CCodeGeneration.csproj">
|
||||
<Project>{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}</Project>
|
||||
<Name>CCodeGeneration</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LwipSnmpCodeGeneration\LwipSnmpCodeGeneration.csproj">
|
||||
<Project>{AABCAB90-1540-45D4-A159-14831A54E9A3}</Project>
|
||||
<Name>LwipSnmpCodeGeneration</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SharpSnmpLib\SharpSnmpLib.Mib.csproj">
|
||||
<Project>{CBE20411-5DB7-487D-825D-7694267BB6F5}</Project>
|
||||
<Name>SharpSnmpLib.Mib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using CCodeGeneration;
|
||||
using Lextm.SharpSnmpLib.Mib;
|
||||
using Lextm.SharpSnmpLib.Mib.Elements.Entities;
|
||||
using Lextm.SharpSnmpLib.Mib.Elements.Types;
|
||||
using LwipSnmpCodeGeneration;
|
||||
|
||||
namespace LwipMibCompiler
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private static readonly Regex _alphaNumericRegex = new Regex("[^a-zA-Z0-9]");
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("lwIP MIB Compiler");
|
||||
Console.WriteLine("");
|
||||
|
||||
// check args
|
||||
if ((args.Length < 2) || String.IsNullOrWhiteSpace(args[0]) || String.IsNullOrWhiteSpace(args[1]))
|
||||
{
|
||||
PrintUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
string mibFile = args[0];
|
||||
if (!File.Exists(mibFile))
|
||||
{
|
||||
Console.WriteLine(String.Format("Unable to find file '{0}'!", mibFile));
|
||||
}
|
||||
|
||||
string destFile = args[1];
|
||||
string destHeaderFile;
|
||||
|
||||
if (Directory.Exists(destFile))
|
||||
{
|
||||
// only directory passed -> create dest filename from mib filename
|
||||
string mibFileName = Path.GetFileNameWithoutExtension(mibFile).ToLowerInvariant();
|
||||
destFile = Path.Combine(destFile, mibFileName + ".c");
|
||||
}
|
||||
|
||||
string destFileExt = Path.GetExtension(destFile);
|
||||
if (!String.IsNullOrEmpty(destFileExt))
|
||||
{
|
||||
destHeaderFile = destFile.Substring(0, destFile.Length - destFileExt.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
destHeaderFile = destFile;
|
||||
}
|
||||
destHeaderFile += ".h";
|
||||
|
||||
for (int i=2; i<args.Length; i++)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(args[i]) && Directory.Exists(args[i]))
|
||||
{
|
||||
MibTypesResolver.RegisterResolver(new FileSystemMibResolver(args[i], true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// read and resolve MIB
|
||||
Console.WriteLine(" Reading MIB file...");
|
||||
|
||||
MibDocument md = new MibDocument(mibFile);
|
||||
MibTypesResolver.ResolveTypes(md.Modules[0]);
|
||||
MibTree mt = new MibTree(md.Modules[0] as MibModule);
|
||||
|
||||
if (mt.Root.Count == 0)
|
||||
{
|
||||
Console.WriteLine("No root element found inside MIB!");
|
||||
return;
|
||||
}
|
||||
|
||||
MibCFile generatedFile = new MibCFile();
|
||||
MibHeaderFile generatedHeaderFile = new MibHeaderFile();
|
||||
|
||||
foreach (MibTreeNode mibTreeNode in mt.Root)
|
||||
{
|
||||
// create LWIP object tree from MIB structure
|
||||
Console.WriteLine(" Creating lwIP object tree " + mibTreeNode.Entity.Name);
|
||||
|
||||
SnmpMib snmpMib = new SnmpMib();
|
||||
snmpMib.Oid = mibTreeNode.Entity.Value;
|
||||
snmpMib.BaseOid = MibTypesResolver.ResolveOid(mibTreeNode.Entity).GetOidValues();
|
||||
snmpMib.Name = mibTreeNode.Entity.Name;
|
||||
|
||||
ProcessMibTreeNode(mibTreeNode, snmpMib);
|
||||
|
||||
// let the tree transform itself depending on node structure
|
||||
snmpMib.Analyze();
|
||||
|
||||
// generate code from LWIP object tree
|
||||
Console.WriteLine(" Generating code " + snmpMib.Name);
|
||||
snmpMib.Generate(generatedFile, generatedHeaderFile);
|
||||
}
|
||||
|
||||
string preservedCode = MibCFile.GetPreservedCode(destFile);
|
||||
if (!string.IsNullOrEmpty(preservedCode))
|
||||
{
|
||||
generatedFile.PreservedCode.Add(new PlainText(preservedCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
generatedFile.PreservedCode.AddRange(generatedFile.Implementation);
|
||||
}
|
||||
generatedFile.Implementation.Clear();
|
||||
|
||||
|
||||
using (StreamWriter fileWriter = new StreamWriter(destHeaderFile))
|
||||
{
|
||||
CGenerator cGenerator = new CGenerator(fileWriter, destHeaderFile, 3, " ", Environment.NewLine);
|
||||
generatedHeaderFile.Save(cGenerator);
|
||||
}
|
||||
using (StreamWriter fileWriter = new StreamWriter(destFile))
|
||||
{
|
||||
CGenerator cGenerator = new CGenerator(fileWriter, destFile, 3, " ", Environment.NewLine);
|
||||
generatedFile.Save(cGenerator);
|
||||
}
|
||||
|
||||
Console.WriteLine(" Done");
|
||||
}
|
||||
|
||||
private static void PrintUsage()
|
||||
{
|
||||
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
|
||||
string appName = Path.GetFileName(codeBase);
|
||||
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(String.Format(" {0} <source MIB file> <dest C file> [<search path 1 for referred MIB's> <search path 2 for referred MIB's> ...]", appName));
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine(" <source MIB file>");
|
||||
Console.WriteLine(" Path and filename of MIB file to convert.");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine(" <dest C file>");
|
||||
Console.WriteLine(" Destination path and file. If a path is passed only, filename is auto");
|
||||
Console.WriteLine(" generated from MIB file name.");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine(" <search path X for referred MIB's>");
|
||||
Console.WriteLine(" It's important to provide all referred MIB's in order to correctly ");
|
||||
Console.WriteLine(" resolve all used types.");
|
||||
Console.WriteLine("");
|
||||
}
|
||||
|
||||
|
||||
#region Generation of LWIP Object Tree
|
||||
|
||||
private static void ProcessMibTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode assignedSnmpNode)
|
||||
{
|
||||
foreach (MibTreeNode mtn in mibTreeNode.ChildNodes)
|
||||
{
|
||||
// in theory container nodes may also be scalars or tables at the same time (for now only process real containers)
|
||||
if (mtn.NodeType == MibTreeNodeType.Container)
|
||||
{
|
||||
SnmpTreeNode snmpTreeNode = GenerateSnmpTreeNode(mtn, assignedSnmpNode);
|
||||
assignedSnmpNode.ChildNodes.Add(snmpTreeNode);
|
||||
|
||||
ProcessMibTreeNode(mtn, snmpTreeNode);
|
||||
}
|
||||
else if ((mtn.NodeType & MibTreeNodeType.Scalar) != 0)
|
||||
{
|
||||
SnmpScalarNode snmpScalarNode = GenerateSnmpScalarNode(mtn, assignedSnmpNode);
|
||||
if (snmpScalarNode != null)
|
||||
{
|
||||
assignedSnmpNode.ChildNodes.Add(snmpScalarNode);
|
||||
}
|
||||
}
|
||||
else if ((mtn.NodeType & MibTreeNodeType.Table) != 0)
|
||||
{
|
||||
SnmpTableNode snmpTableNode = GenerateSnmpTableNode(mtn, assignedSnmpNode);
|
||||
if (snmpTableNode != null)
|
||||
{
|
||||
assignedSnmpNode.ChildNodes.Add(snmpTableNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static SnmpTreeNode GenerateSnmpTreeNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
|
||||
{
|
||||
SnmpTreeNode result = new SnmpTreeNode(parentNode);
|
||||
result.Name = _alphaNumericRegex.Replace(mibTreeNode.Entity.Name, "").ToLowerInvariant();
|
||||
result.Oid = mibTreeNode.Entity.Value;
|
||||
result.FullOid = MibTypesResolver.ResolveOid(mibTreeNode.Entity).GetOidString();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static SnmpScalarNode GenerateSnmpScalarNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
|
||||
{
|
||||
ObjectType ote = mibTreeNode.Entity as ObjectType;
|
||||
if (ote != null)
|
||||
{
|
||||
return GenerateSnmpScalarNode(ote, parentNode, ignoreAccessibleFlag);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static SnmpScalarNode GenerateSnmpScalarNode(ObjectType ote, SnmpTreeNode parentNode, bool ignoreAccessibleFlag = false)
|
||||
{
|
||||
SnmpScalarNode result;
|
||||
|
||||
ITypeAssignment mibType = ote.BaseType;
|
||||
IntegerType it = (mibType as IntegerType);
|
||||
if (it != null)
|
||||
{
|
||||
if (ote.ReferredType.Name == Symbol.TruthValue.ToString())
|
||||
{
|
||||
result = new SnmpScalarNodeTruthValue(parentNode);
|
||||
}
|
||||
else if ((it.Type == IntegerType.Types.Integer) || (it.Type == IntegerType.Types.Integer32))
|
||||
{
|
||||
result = new SnmpScalarNodeInt(parentNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(String.Format("Unsupported IntegerType '{0}'!", it.Type));
|
||||
return null;
|
||||
}
|
||||
if (it.IsEnumeration)
|
||||
{
|
||||
result.Restrictions.AddRange(CreateRestrictions(it.Enumeration));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Restrictions.AddRange(CreateRestrictions(it.Ranges));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UnsignedType ut = (mibType as UnsignedType);
|
||||
if (ut != null)
|
||||
{
|
||||
if ((ut.Type == UnsignedType.Types.Unsigned32) ||
|
||||
(ut.Type == UnsignedType.Types.Gauge32))
|
||||
{
|
||||
result = new SnmpScalarNodeUint(SnmpDataType.Gauge, parentNode);
|
||||
}
|
||||
else if (ut.Type == UnsignedType.Types.Counter32)
|
||||
{
|
||||
result = new SnmpScalarNodeUint(SnmpDataType.Counter, parentNode);
|
||||
}
|
||||
else if (ut.Type == UnsignedType.Types.TimeTicks)
|
||||
{
|
||||
result = new SnmpScalarNodeUint(SnmpDataType.TimeTicks, parentNode);
|
||||
}
|
||||
else if (ut.Type == UnsignedType.Types.Counter64)
|
||||
{
|
||||
result = new SnmpScalarNodeCounter64(parentNode);
|
||||
if ((ut.Ranges != null) && (ut.Ranges.Count > 0))
|
||||
{
|
||||
Console.WriteLine(String.Format("Generation of ranges is not supported for Counter64 type!"));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(String.Format("Unsupported UnsignedType '{0}'!", ut.Type));
|
||||
return null;
|
||||
}
|
||||
result.Restrictions.AddRange(CreateRestrictions(ut.Ranges));
|
||||
}
|
||||
else if (mibType is IpAddressType)
|
||||
{
|
||||
result = new SnmpScalarNodeOctetString(SnmpDataType.IpAddress, parentNode);
|
||||
result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
|
||||
}
|
||||
else if (mibType is OpaqueType)
|
||||
{
|
||||
result = new SnmpScalarNodeOctetString(SnmpDataType.Opaque, parentNode);
|
||||
result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
|
||||
}
|
||||
else if (mibType is OctetStringType)
|
||||
{
|
||||
result = new SnmpScalarNodeOctetString(SnmpDataType.OctetString, parentNode);
|
||||
result.Restrictions.AddRange(CreateRestrictions((mibType as OctetStringType).Size));
|
||||
}
|
||||
else if (mibType is ObjectIdentifierType)
|
||||
{
|
||||
result = new SnmpScalarNodeObjectIdentifier(parentNode);
|
||||
}
|
||||
else if (mibType is BitsType)
|
||||
{
|
||||
result = new SnmpScalarNodeBits(parentNode, (uint)((mibType as BitsType).Map.GetHighestValue() + 1));
|
||||
result.Restrictions.AddRange(CreateRestrictions(mibType as BitsType));
|
||||
}
|
||||
else
|
||||
{
|
||||
TypeAssignment ta = mibType as TypeAssignment;
|
||||
if (ta != null)
|
||||
{
|
||||
Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}', Type='{2}'!", ta.Module.Name, ta.Name, ta.Type));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(String.Format("Unsupported BaseType: Module='{0}', Name='{1}'!", mibType.Module, mibType.Name));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
result.Name = _alphaNumericRegex.Replace(ote.Name, "").ToLowerInvariant();
|
||||
result.Oid = ote.Value;
|
||||
|
||||
if (ote.Access == MaxAccess.readWrite)
|
||||
{
|
||||
result.AccessMode = SnmpAccessMode.ReadWrite;
|
||||
}
|
||||
else if (ote.Access == MaxAccess.readOnly)
|
||||
{
|
||||
result.AccessMode = SnmpAccessMode.ReadOnly;
|
||||
}
|
||||
else if (ote.Access == MaxAccess.readCreate)
|
||||
{
|
||||
result.AccessMode = SnmpAccessMode.ReadOnly;
|
||||
}
|
||||
else if (ignoreAccessibleFlag && (ote.Access == MaxAccess.notAccessible))
|
||||
{
|
||||
result.AccessMode = SnmpAccessMode.NotAccessible;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not accessible or unsupported accress type
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<IRestriction> CreateRestrictions(ValueRanges ranges)
|
||||
{
|
||||
List<IRestriction> result = new List<IRestriction>();
|
||||
|
||||
if (ranges != null)
|
||||
{
|
||||
foreach (ValueRange range in ranges)
|
||||
{
|
||||
if (!range.End.HasValue)
|
||||
{
|
||||
result.Add(new IsEqualRestriction(range.Start));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(new IsInRangeRestriction(range.Start, range.End.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static IEnumerable<IRestriction> CreateRestrictions(ValueMap map)
|
||||
{
|
||||
if ((map != null) && (map.Count > 0))
|
||||
{
|
||||
return CreateRestrictions(map.GetContinousRanges());
|
||||
}
|
||||
|
||||
return new List<IRestriction>();
|
||||
}
|
||||
|
||||
private static IEnumerable<IRestriction> CreateRestrictions(BitsType bt)
|
||||
{
|
||||
List<IRestriction> result = new List<IRestriction>();
|
||||
|
||||
if ((bt != null) && (bt.Map != null))
|
||||
{
|
||||
result.Add(new BitMaskRestriction(bt.Map.GetBitMask()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static SnmpTableNode GenerateSnmpTableNode(MibTreeNode mibTreeNode, SnmpTreeNode parentNode)
|
||||
{
|
||||
SnmpTableNode result = new SnmpTableNode(parentNode);
|
||||
result.Name = mibTreeNode.Entity.Name;
|
||||
result.Oid = mibTreeNode.Entity.Value;
|
||||
|
||||
// expect exactly one row entry
|
||||
if ((mibTreeNode.ChildNodes.Count != 1) || ((mibTreeNode.ChildNodes[0].NodeType & MibTreeNodeType.TableRow) == 0) || (mibTreeNode.ChildNodes[0].Entity.Value != 1))
|
||||
{
|
||||
Console.WriteLine("Found table with unsupported properties! Table needs exactly one (fixed) TableRow with OID=1 ! (" + mibTreeNode.Entity.Name + ")");
|
||||
return null;
|
||||
}
|
||||
|
||||
MibTreeNode rowNode = mibTreeNode.ChildNodes[0];
|
||||
|
||||
ObjectType rot = rowNode.Entity as ObjectType;
|
||||
if (rot != null)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(rot.Augments))
|
||||
{
|
||||
result.AugmentedTableRow = rot.Augments;
|
||||
|
||||
// the indeces from another table shall be used because this table is only an extension of it
|
||||
rot = MibTypesResolver.ResolveDeclaration(rot.Module, rot.Augments) as ObjectType;
|
||||
}
|
||||
|
||||
if (rot.Indices != null)
|
||||
{
|
||||
foreach (string index in rot.Indices)
|
||||
{
|
||||
ObjectType indexEntity = MibTypesResolver.ResolveDeclaration(rot.Module, index) as ObjectType;
|
||||
if (indexEntity == null)
|
||||
{
|
||||
Console.WriteLine(String.Format("Could not resolve index '{0}' for table '{1}'! Table omitted!", index, result.Name));
|
||||
return null;
|
||||
}
|
||||
|
||||
result.IndexNodes.Add(GenerateSnmpScalarNode(indexEntity, parentNode, ignoreAccessibleFlag: true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.IndexNodes.Count == 0)
|
||||
{
|
||||
// a table cannot be used without index
|
||||
Console.WriteLine("Found table without any index column ! (" + mibTreeNode.Entity.Name + ")");
|
||||
return null;
|
||||
}
|
||||
|
||||
// add child nodes
|
||||
foreach (MibTreeNode cellNode in rowNode.ChildNodes)
|
||||
{
|
||||
SnmpScalarNode ssn = GenerateSnmpScalarNode(cellNode, parentNode);
|
||||
if (ssn != null)
|
||||
{
|
||||
result.CellNodes.Add(ssn);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die mit einer Assembly verknüpft sind.
|
||||
[assembly: AssemblyTitle("ConsoleApplication28")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ConsoleApplication28")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("0abf7541-6a96-43cd-9e24-462e074b2c96")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
namespace LwipMibViewer
|
||||
{
|
||||
partial class FormMain
|
||||
{
|
||||
/// <summary>
|
||||
/// Erforderliche Designervariable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Verwendete Ressourcen bereinigen.
|
||||
/// </summary>
|
||||
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Vom Windows Form-Designer generierter Code
|
||||
|
||||
/// <summary>
|
||||
/// Erforderliche Methode für die Designerunterstützung.
|
||||
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
|
||||
this.treeMib = new System.Windows.Forms.TreeView();
|
||||
this.imagelistTreeNodeImages = new System.Windows.Forms.ImageList(this.components);
|
||||
this.splitContainerMain = new System.Windows.Forms.SplitContainer();
|
||||
this.listviewNodeDetails = new System.Windows.Forms.ListView();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.toolStripMain = new System.Windows.Forms.ToolStrip();
|
||||
this.toolbuttonOpenMib = new System.Windows.Forms.ToolStripButton();
|
||||
this.dialogOpenMib = new System.Windows.Forms.OpenFileDialog();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainerMain)).BeginInit();
|
||||
this.splitContainerMain.Panel1.SuspendLayout();
|
||||
this.splitContainerMain.Panel2.SuspendLayout();
|
||||
this.splitContainerMain.SuspendLayout();
|
||||
this.toolStripMain.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// treeMib
|
||||
//
|
||||
this.treeMib.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.treeMib.ImageIndex = 0;
|
||||
this.treeMib.ImageList = this.imagelistTreeNodeImages;
|
||||
this.treeMib.Location = new System.Drawing.Point(0, 0);
|
||||
this.treeMib.Name = "treeMib";
|
||||
this.treeMib.SelectedImageIndex = 0;
|
||||
this.treeMib.Size = new System.Drawing.Size(1028, 418);
|
||||
this.treeMib.TabIndex = 0;
|
||||
this.treeMib.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeMib_AfterSelect);
|
||||
//
|
||||
// imagelistTreeNodeImages
|
||||
//
|
||||
this.imagelistTreeNodeImages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imagelistTreeNodeImages.ImageStream")));
|
||||
this.imagelistTreeNodeImages.TransparentColor = System.Drawing.Color.Transparent;
|
||||
this.imagelistTreeNodeImages.Images.SetKeyName(0, "ntimgContainer");
|
||||
this.imagelistTreeNodeImages.Images.SetKeyName(1, "ntimgTable");
|
||||
this.imagelistTreeNodeImages.Images.SetKeyName(2, "ntimgRow");
|
||||
this.imagelistTreeNodeImages.Images.SetKeyName(3, "ntimgColumn");
|
||||
this.imagelistTreeNodeImages.Images.SetKeyName(4, "ntimgScalar");
|
||||
this.imagelistTreeNodeImages.Images.SetKeyName(5, "ntimgUnknown");
|
||||
//
|
||||
// splitContainerMain
|
||||
//
|
||||
this.splitContainerMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.splitContainerMain.Location = new System.Drawing.Point(0, 25);
|
||||
this.splitContainerMain.Name = "splitContainerMain";
|
||||
this.splitContainerMain.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||
//
|
||||
// splitContainerMain.Panel1
|
||||
//
|
||||
this.splitContainerMain.Panel1.Controls.Add(this.treeMib);
|
||||
//
|
||||
// splitContainerMain.Panel2
|
||||
//
|
||||
this.splitContainerMain.Panel2.Controls.Add(this.listviewNodeDetails);
|
||||
this.splitContainerMain.Size = new System.Drawing.Size(1028, 625);
|
||||
this.splitContainerMain.SplitterDistance = 418;
|
||||
this.splitContainerMain.TabIndex = 1;
|
||||
//
|
||||
// listviewNodeDetails
|
||||
//
|
||||
this.listviewNodeDetails.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnHeader1,
|
||||
this.columnHeader2});
|
||||
this.listviewNodeDetails.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.listviewNodeDetails.FullRowSelect = true;
|
||||
this.listviewNodeDetails.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
|
||||
this.listviewNodeDetails.Location = new System.Drawing.Point(0, 0);
|
||||
this.listviewNodeDetails.Name = "listviewNodeDetails";
|
||||
this.listviewNodeDetails.Size = new System.Drawing.Size(1028, 203);
|
||||
this.listviewNodeDetails.TabIndex = 0;
|
||||
this.listviewNodeDetails.UseCompatibleStateImageBehavior = false;
|
||||
this.listviewNodeDetails.View = System.Windows.Forms.View.Details;
|
||||
//
|
||||
// columnHeader1
|
||||
//
|
||||
this.columnHeader1.Text = "";
|
||||
this.columnHeader1.Width = 150;
|
||||
//
|
||||
// columnHeader2
|
||||
//
|
||||
this.columnHeader2.Text = "";
|
||||
this.columnHeader2.Width = 777;
|
||||
//
|
||||
// toolStripMain
|
||||
//
|
||||
this.toolStripMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.toolbuttonOpenMib});
|
||||
this.toolStripMain.Location = new System.Drawing.Point(0, 0);
|
||||
this.toolStripMain.Name = "toolStripMain";
|
||||
this.toolStripMain.Size = new System.Drawing.Size(1028, 25);
|
||||
this.toolStripMain.TabIndex = 2;
|
||||
//
|
||||
// toolbuttonOpenMib
|
||||
//
|
||||
this.toolbuttonOpenMib.Image = ((System.Drawing.Image)(resources.GetObject("toolbuttonOpenMib.Image")));
|
||||
this.toolbuttonOpenMib.Name = "toolbuttonOpenMib";
|
||||
this.toolbuttonOpenMib.Size = new System.Drawing.Size(65, 22);
|
||||
this.toolbuttonOpenMib.Text = "Open...";
|
||||
this.toolbuttonOpenMib.Click += new System.EventHandler(this.toolbuttonOpenMib_Click);
|
||||
//
|
||||
// FormMain
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1028, 650);
|
||||
this.Controls.Add(this.splitContainerMain);
|
||||
this.Controls.Add(this.toolStripMain);
|
||||
this.Name = "FormMain";
|
||||
this.Text = "MIB Viewer";
|
||||
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
|
||||
this.splitContainerMain.Panel1.ResumeLayout(false);
|
||||
this.splitContainerMain.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainerMain)).EndInit();
|
||||
this.splitContainerMain.ResumeLayout(false);
|
||||
this.toolStripMain.ResumeLayout(false);
|
||||
this.toolStripMain.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TreeView treeMib;
|
||||
private System.Windows.Forms.SplitContainer splitContainerMain;
|
||||
private System.Windows.Forms.ListView listviewNodeDetails;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader1;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader2;
|
||||
private System.Windows.Forms.ImageList imagelistTreeNodeImages;
|
||||
private System.Windows.Forms.ToolStrip toolStripMain;
|
||||
private System.Windows.Forms.ToolStripButton toolbuttonOpenMib;
|
||||
private System.Windows.Forms.OpenFileDialog dialogOpenMib;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Windows.Forms;
|
||||
using Lextm.SharpSnmpLib.Mib;
|
||||
using Lextm.SharpSnmpLib.Mib.Elements;
|
||||
using Lextm.SharpSnmpLib.Mib.Elements.Types;
|
||||
using Lextm.SharpSnmpLib.Mib.Elements.Entities;
|
||||
using System.IO;
|
||||
|
||||
namespace LwipMibViewer
|
||||
{
|
||||
public partial class FormMain : Form
|
||||
{
|
||||
readonly ListViewGroup listviewgroupAbstract;
|
||||
readonly ListViewGroup listviewgroupElement;
|
||||
readonly ListViewGroup listviewgroupBaseType;
|
||||
readonly ListViewGroup listviewgroupTypeChain;
|
||||
|
||||
public FormMain()
|
||||
{
|
||||
this.Font = SystemInformation.MenuFont;
|
||||
InitializeComponent();
|
||||
|
||||
this.listviewgroupAbstract = new ListViewGroup("Abstract", System.Windows.Forms.HorizontalAlignment.Left);
|
||||
this.listviewgroupElement = new ListViewGroup("Element Properties", System.Windows.Forms.HorizontalAlignment.Left);
|
||||
this.listviewgroupBaseType = new ListViewGroup("Element Base Type", System.Windows.Forms.HorizontalAlignment.Left);
|
||||
this.listviewgroupTypeChain = new ListViewGroup("Element Type Chain", System.Windows.Forms.HorizontalAlignment.Left);
|
||||
this.listviewNodeDetails.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] {
|
||||
listviewgroupAbstract,
|
||||
listviewgroupElement,
|
||||
listviewgroupBaseType,
|
||||
listviewgroupTypeChain});
|
||||
|
||||
try
|
||||
{
|
||||
DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(Application.ExecutablePath));
|
||||
if (dirInfo != null)
|
||||
{
|
||||
dirInfo = dirInfo.Parent;
|
||||
if (dirInfo != null)
|
||||
{
|
||||
dirInfo = dirInfo.Parent;
|
||||
if (dirInfo != null)
|
||||
{
|
||||
dirInfo = new DirectoryInfo(Path.Combine(dirInfo.FullName, "Mibs"));
|
||||
if (dirInfo.Exists)
|
||||
{
|
||||
MibTypesResolver.RegisterResolver(new FileSystemMibResolver(dirInfo.FullName, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
#region GUI Event Handler
|
||||
|
||||
private void toolbuttonOpenMib_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
if (this.dialogOpenMib.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
OpenMib(this.dialogOpenMib.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void treeMib_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
listviewNodeDetails.Items.Clear();
|
||||
|
||||
if (e.Node != null)
|
||||
{
|
||||
MibTreeNode mtn = e.Node.Tag as MibTreeNode;
|
||||
if (mtn != null)
|
||||
{
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Abstract", mtn.NodeType.ToString() }, this.listviewgroupAbstract));
|
||||
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Module", (mtn.Entity.Module != null) ? mtn.Entity.Module.Name : "" }, this.listviewgroupElement));
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Type", mtn.Entity.GetType().Name }, this.listviewgroupElement));
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Name", mtn.Entity.Name }, this.listviewgroupElement));
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Description", mtn.Entity.Description }, this.listviewgroupElement));
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "OID", mtn.Entity.Value.ToString() }, this.listviewgroupElement));
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Full OID", MibTypesResolver.ResolveOid(mtn.Entity).GetOidString() }, this.listviewgroupElement));
|
||||
if (mtn.Entity is ObjectType)
|
||||
{
|
||||
listviewNodeDetails.Items.Add(new ListViewItem(new string[] { "Access", (mtn.Entity as ObjectType).Access.ToString() }, this.listviewgroupElement));
|
||||
}
|
||||
|
||||
ITypeReferrer tr = mtn.Entity as ITypeReferrer;
|
||||
if (tr != null)
|
||||
{
|
||||
ShowTypeDetails(listviewNodeDetails, this.listviewgroupBaseType, tr.BaseType);
|
||||
ShowTypeChain(listviewNodeDetails, tr.ReferredType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private void OpenMib(string file)
|
||||
{
|
||||
try
|
||||
{
|
||||
MibDocument md = new MibDocument(file);
|
||||
MibTypesResolver.ResolveTypes(md.Modules[0]);
|
||||
|
||||
this.treeMib.Nodes.Clear();
|
||||
this.listviewNodeDetails.Items.Clear();
|
||||
|
||||
MibTree mt = new MibTree(md.Modules[0] as MibModule);
|
||||
foreach (MibTreeNode mibTreeNode in mt.Root)
|
||||
{
|
||||
AddNode(mibTreeNode, this.treeMib.Nodes);
|
||||
|
||||
foreach (TreeNode node in this.treeMib.Nodes)
|
||||
{
|
||||
node.Expand();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNode(MibTreeNode mibNode, TreeNodeCollection parentNodes)
|
||||
{
|
||||
int imgIndex = 5; //unknown
|
||||
if ((mibNode.NodeType & MibTreeNodeType.Table) != 0)
|
||||
{
|
||||
imgIndex = 1;
|
||||
}
|
||||
else if ((mibNode.NodeType & MibTreeNodeType.TableRow) != 0)
|
||||
{
|
||||
imgIndex = 2;
|
||||
}
|
||||
else if ((mibNode.NodeType & MibTreeNodeType.TableCell) != 0)
|
||||
{
|
||||
imgIndex = 3;
|
||||
}
|
||||
else if ((mibNode.NodeType & MibTreeNodeType.Scalar) != 0)
|
||||
{
|
||||
imgIndex = 4;
|
||||
}
|
||||
else if ((mibNode.NodeType & MibTreeNodeType.Container) != 0)
|
||||
{
|
||||
imgIndex = 0;
|
||||
}
|
||||
|
||||
TreeNode newNode = new TreeNode(mibNode.Entity.Name, imgIndex, imgIndex);
|
||||
newNode.Tag = mibNode;
|
||||
|
||||
parentNodes.Add(newNode);
|
||||
|
||||
foreach (MibTreeNode child in mibNode.ChildNodes)
|
||||
{
|
||||
AddNode(child, newNode.Nodes);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowTypeChain(ListView lv, ITypeAssignment type)
|
||||
{
|
||||
ShowTypeDetails(lv, this.listviewgroupTypeChain, type);
|
||||
|
||||
ITypeReferrer tr = type as ITypeReferrer;
|
||||
if ((tr != null) && (tr.ReferredType != null))
|
||||
{
|
||||
lv.Items.Add(new ListViewItem(new string[] { " >>>", "" }, this.listviewgroupTypeChain));
|
||||
ShowTypeChain(listviewNodeDetails, tr.ReferredType);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowTypeDetails(ListView lv, ListViewGroup lvg, ITypeAssignment type)
|
||||
{
|
||||
lv.Items.Add(new ListViewItem(new string[] { "Module", (type.Module != null) ? type.Module.Name : "" }, lvg));
|
||||
lv.Items.Add(new ListViewItem(new string[] { "Type", type.GetType().Name }, lvg));
|
||||
lv.Items.Add(new ListViewItem(new string[] { "Name", type.Name }, lvg));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="imagelistTreeNodeImages.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="imagelistTreeNodeImages.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
|
||||
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
||||
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABo
|
||||
IQAAAk1TRnQBSQFMAgEBBgEAARABAAEQAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
|
||||
AwABIAMAAQEBAAEgBgABIBIAAwQBBQMWAR4DIgEyAzEBTwJGAUQBhwMvAUsDHgErAxsBJgMYASIDFQEd
|
||||
AxIBGAMNARIDCgENAwcBCQMEAQUDAQECAwQBBQMWAR4DIgEyAzEBTgJGAUQBhwMvAUsDHgErAxsBJgMb
|
||||
ASYDIQExAyEBMAMdASoDGwEmAxgBIQMLAQ8DAQECgAADAgEDAwwBEAMrAUMCRgFEAYIC/wHwAf8CRgFE
|
||||
AYIDKgFAAw8BFAMNAREDCwEPAwkBDAMHAQoDBQEHAwQBBQMCAQMDAAEBAwIBAwMLAQ8DKwFDAkYBRAGC
|
||||
Av8B8AH/AkYBRAGCAyoBQAMOARMDEgEZAT0COwFpAVwBRQFCAawBZwE+AToBxAFaAUUBQwGqATwBOwE6
|
||||
AWYDEAEWAwABAYQAAx4BKwJEAUIBewL/AfAB/wLpAdoD/wHxAf8CRAFCAXsDHgErJAADHgErAkQBQgF7
|
||||
Av8B8AH/AukB2gP/AfEB/wJEAUIBewMeASsBLgItAUcBdwFHATwByQG7AVQBPQHxA+4B/wG7AVMBPAHx
|
||||
AXcBRgE8AckBLgItAUeEAAMdASoCRAFCAXcC/wHwAf8B6wHdAbEB/wH3AcEBNwH/Ae0B3wGzA/8B8gH/
|
||||
AkQBQgF3Ax0BKhwAAx0BKgJEAUIBdwL/AfAB/wLpAdoB/wLqAdwB/wLrAd4D/wHyAf8CRAFCAXcBZAFJ
|
||||
AUIBrwG2AVkBQQHxAc0BVAEyAf8BvQF5AWIB/wHFAVABLgH/AbEBUQE1AfEBXAFIAUQBn4QAAkMBQQF2
|
||||
Av8B8AH/AukB2gH/AecBqwEhAf8B5wGrASEB/wHnAasBIQH/AeoB2wGwA/8B9AH/AkMBQQF2Ax0BKhgA
|
||||
AkMBQQF2Av8B8AH/AukB2gH/AuoB3AH/AusB3gH/AuwB3wH/Au0B4QP/AfQB/wGAAUQBMQHaAc4BcAFN
|
||||
AfwBugFMASoB/wPSAf8BvgGLAXgB/wG7AVIBMgH8AW8BSQE/AbqEAAMdASkCQwFBAXQC/wHxAf8B5wHX
|
||||
AasB/wHXAZYBDAH/AdcBlgEMAf8B1wGWAQwB/wHoAdgBrgP/AfUB/wJDAUEBdAMdASkUAAMdASkCQwFB
|
||||
AXQC/wHxAf8C6wHeAf8C7AHfAf8C7QHhAf8C7gHjAf8C7wHlAf8BzQF5AV4B/wHOAXcBWAH3AbwBVAEy
|
||||
Af8BtAFMASoB/wPmAf8BtwFlAUsB8AFdAUkBRAGdiAADHQEpAkIBQQFyAv8B8gH/AeUB1AGpAf8BzQGJ
|
||||
AQAB/wHNAYkBAAH/Ac0BiQEAAf8B6AHXAa8D/wH3Af8CQgFBAXIDHAEoFAADHQEpAkIBQQFyAv8B8gH/
|
||||
Au0B4QH/Au4B4wH/Au8B5QH/AvAB5wH/AeABuwGqAf8BzgFpAUgB/wHjAcsBwQH5BP8B3gHHAb0B9QF+
|
||||
AU8BQgHEAi0BLAFFjAADHAEoAkEBQAFxAv8B9AH/AecB1gGsAf8B0QGOAQQB/wHRAY4BBAH/AdEBjgEE
|
||||
Af8B7AHbAbMD/wH4Af8CQQFAAXEDHAEoFAADHAEoAkEBQAFxAv8B9AH/Au8B5QH/AvAB5wH/AvEB6QH/
|
||||
AvMB6gH/AeQBvgGsAf8B1AGBAWIB/wGGAUoBNAHXAWYBTQFEAaoCLQEsAUWUAAMcAScCQQFAAW8C/wH1
|
||||
Af8B7AHcAbMB/wHfAaEBFwH/Ad8BoQEXAf8B3wGhARcB/wHxAeIBuwP/AfoB/wJBAUABbwMcAScUAAMc
|
||||
AScCQQFAAW8C/wH1Af8C8QHpAf8C8wHqAf8C9AHsAf8C9QHuAf8C9gHwA/8B+gH/AkEBQAFvAxwBJ5gA
|
||||
AxwBJwJAAT8BbQL/AfcB/wHyAeMBuwH/AfABuAEuAf8B8AG4AS4B/wHwAbgBLgH/AvgB9AP/AfsB/wJA
|
||||
AT8BbQMcAScUAAMcAScCQAE/AW0C/wH3Af8C9AHsAf8C9QHuAf8C9gHwAf8C9wHyAf8C+AH0A/8B+wH/
|
||||
AkABPwFtAxwBJ5gAAxsBJgJAAT8BbAL/AfgB/wH3AeoBwwH/Af0ByQE/Af8B+QHsAccB/wL7AfcB/wL8
|
||||
AfkD/wH8Af8CQAE/AWwDGwEmFAADGwEmAkABPwFsAv8B+AH/AvYB8AH/AvcB8gH/AvgB9AH/AvsB9wH/
|
||||
AvwB+QP/AfwB/wJAAT8BbAMbASaYAAMbASYCPwE+AWsC/wH6Af8C+AH0Af8C+wH3Af8C3wHVAf8CyQG5
|
||||
Af8C4AHWA/8B/gH/Aj8BPgFrGAADGwEmAj8BPgFrAv8B+gH/AvgB9AH/AvsB9wH/At8B1QH/AskBuQH/
|
||||
AuAB1gP/Af4B/wI/AT4Ba5wAAxoBJQI/AT0BaQL/AfsB/wL8AfkB/wK8AawB/wQAArwBrAP/Af4B/wI/
|
||||
AT0BaRwAAxoBJQI/AT0BaQL/AfsB/wL8AfkB/wK8AawB/wQAArwBrAP/Af4B/wI/AT0BaaAAAxoBJQI+
|
||||
AT0BaAL/AfwB/wLLAcEB/wKgAZAB/wLLAcED/wH+Af8CPgE9AWggAAMaASUCPgE9AWgC/wH8Af8CywHB
|
||||
Af8CoAGQAf8CywHBA/8B/gH/Aj4BPQFopAADGgElAj4BPQFnAv8B/gP/Af4D/wH+Bf8CPgE9AWckAAMa
|
||||
ASUCPgE9AWcC/wH+A/8B/gP/Af4F/wI+AT0BZ6gAAxoBJAI+AT0BZgI+AT0BZgI+AT0BZgI+AT0BZgMx
|
||||
AU0oAAMaASQCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYDMQFNlAADIQEwAUABRgFIAXwBQwFOAVIBkgMF
|
||||
AQccAAMHAQkDEAEWAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEa
|
||||
AxABFgMHAQkDBwEJAxABFgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEa
|
||||
AxMBGgMQARYDBwEJAwcBCQMQARYDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEaAxMBGgMTARoDEwEa
|
||||
AxMBGgMTARoDEAEWAwcBCQwAAjIBMwFQAUMBUQFXAZkBRQFkAXQBwAFYAYsBogHgATwBWAFqAcEDEwEa
|
||||
AwUBBxgAAjwBOwFpAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGH
|
||||
AkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAjwBOwFpAjkBNAFpAkABNwGHAkABNwGH
|
||||
AkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGHAkABNwGH
|
||||
AkABNwGHAkABNwGHAjkBNAFpAjwBOwFpAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGH
|
||||
AkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAkYBRAGHAjwBOwFpAw0BEQMa
|
||||
ASQBRAFNAVEBmAE8AYkBrAHyAWcBrwHTAfoBggHLAewB/wGFAc4B7gH/ARUBWwGCAe8BOgFXAWYBxAE6
|
||||
AVcBZgHEAT4BWgFqAb4BPgFaAWoBvgE+AVoBagG+AUQBTQFRAZgDGgEkAw0BEQJGAUMBgQL5AekB/wLz
|
||||
AeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLz
|
||||
AeIB/wLzAeIB/wL5AekB/wJGAUMBgQJDAToBgQL5AekB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLz
|
||||
AeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wL5AekB/wJDAToBgQJG
|
||||
AUMBgQL5AekB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLzAeIB/wLz
|
||||
AeIB/wLzAeIB/wLzAeIB/wLzAeIB/wL5AekB/wJGAUMBgQMHAQkDDQESAUIBWwFmAbIBiAHQAe8B/wF9
|
||||
AcoB6QH/AX0BygHpAf8BhwHQAe8B/wEkAXsBqQH/AX0BvAHbAf8BfQG8AdsB/wGNAdEB8wH/AY0B0QHz
|
||||
Af8BkAHUAfUB/wFCAVsBZgGyATACMQFNAwcBCQJEAUMBegL0AeQC/wHMAUIB/wH+AcsBQQH/AewB0gGG
|
||||
Af8C2gHJAf8C2AHHAf8C1gHFAf8C1AHDAf8C0wHCAf8C0QHAAf8CzwG+Af8CzgG9Af8CzQG8Af8C9AHk
|
||||
Af8CRAFDAXoCRgE+AXoC9AHkAv8BzAFDAf8B/gHLAUIB/wHsAdIBhgH/AtoByQH/AtgBxwH/AtYBxQH/
|
||||
AtQBwwH/AtMBwgH/AtEBwAH/As8BvgH/As4BvQH/As0BvAH/AvQB5AH/AkYBPgF6AkQBQwF6AvQB5AL/
|
||||
AcwBQgH/Af4BywFBAf8B7AHSAYYB/wLaAckB/wLYAccB/wHnAWEBPwH/AecBYQE/Af8B5wFhAT8B/wHn
|
||||
AWEBPwH/As8BvgH/As4BvQH/As0BvAH/AvQB5AH/AkQBQwF6CAABQwFXAWABpAGKAdMB8AH/AYIBzQHr
|
||||
Af8BggHNAesB/wGKAdMB8AH/ASQBfAGrAf8BegG5AdgB/wF6AbkB2AH/AYoBzgHwAf8BigHOAfAB/wGP
|
||||
AdMB9AH/AfQBtgEsAf8BQwFXAWABpAQAAkQBQgF3AvUB5gL/AcwBQgL/Ae4BiAH/AewB0gGGAf8C9QHu
|
||||
Af8C9QHuAf8C1gHFAf8C9QHuAf8C9QHuAf8C0QHAAf8C9QHuAf8C9QHuAf8CzQG8Af8C9QHmAf8CRAFC
|
||||
AXcCRwE/AXcC9QHmAv8BzAFDAv8B7gGIAf8B7AHSAYYB/wL1Ae4B/wL1Ae4B/wLWAcUB/wL1Ae4B/wL1
|
||||
Ae4B/wLRAcAB/wL1Ae4B/wL1Ae4B/wLNAbwB/wL1AeYB/wJHAT8BdwJEAUIBdwL1AeYC/wHMAUIC/wHu
|
||||
AYgB/wHsAdIBhgH/AvUB7gH/AvUB7gH/AdkBWAE2Af8B8gHJAbgB/wHyAckBuAH/AdkBWAE2Af8C9QHu
|
||||
Af8C9QHuAf8CzQG8Af8C9QHmAf8CRAFCAXcIAAFDAVUBXgGeAY4B1gHyAf8BhwHQAe0B/wGHAdAB7QH/
|
||||
AY4B1gHyAf8BJgGCAa8B/wF7AboB2AH/AXsBugHYAf8BiwHPAfEB/wGLAc8B8QH/AZEB1QH1Af8B/gHJ
|
||||
AT8B/wFDAVUBXgGeBAACQwFBAXUC9gHpAv8BzAFCAf8B/gHLAUEB/wHsAdIBhgH/AtoByQH/AtgBxwH/
|
||||
AtwBzAH/AtQBwwH/AtMBwgH/AtgByAH/As8BvgH/As4BvQH/As0BvAH/AvYB6QH/AkMBQQF1AkcBPwF1
|
||||
AvYB6QL/AcwBQwH/Af4BywFCAf8B7AHSAYYB/wLaAckB/wLYAccB/wLcAcwB/wLUAcMB/wLTAcIB/wLY
|
||||
AcgB/wLPAb4B/wLOAb0B/wLNAbwB/wL2AekB/wJHAT8BdQJDAUEBdQL2AekC/wHMAUIB/wH+AcsBQQH/
|
||||
AewB0gGGAf8C2gHJAf8C2AHHAf8ByAFPAS0B/wHeAbYBngH/Ad4BtQGdAf8ByAFPAS0B/wLPAb4B/wLO
|
||||
Ab0B/wLNAbwB/wL2AekB/wJDAUEBdQgAAUQBVQFdAZsBkgHaAfQB/wGLAdQB8AH/AYsB1AHwAf8BkgHa
|
||||
AfQB/wEpAYUBswH/AX0BvAHaAf8BfQG8AdoB/wGNAdEB8wH/AY0B0QHzAf8BkwHXAfYB/wLrAd0B/wFE
|
||||
AVUBXQGbBAACQgFBAXMC9wHrAv8BzAFCAv8B7gGIAf8B7AHSAYYB/wL3AfEB/wL3AfEB/wLWAcUB/wL3
|
||||
AfEB/wL3AfEB/wLRAcAB/wL3AfEB/wL3AfEB/wLNAbwB/wL3AesB/wJCAUEBcwJHAT8BcwL3AesC/wHM
|
||||
AUMC/wHuAYgB/wHsAdIBhgH/AvcB8QH/AvcB8QH/AtYBxQH/AvcB8QH/AvcB8QH/AtEBwAH/AvcB8QH/
|
||||
AvcB8QH/As0BvAH/AvcB6wH/AkcBPwFzAkIBQQFzAvcB6wL/AcwBQgL/Ae4BiAH/AewB0gGGAf8C9wHx
|
||||
Af8C9wHxAf8BuAFHASUB/wHzAcsBuQH/AfMBywG5Af8BuAFHASUB/wL3AfEB/wL3AfEB/wLNAbwB/wL3
|
||||
AesB/wJCAUEBcwgAAUQBUwFbApcB3gH2Af8BkAHYAfIB/wGQAdgB8gH/AZcB3gH2Af8BKwGJAbcB/wGA
|
||||
Ab0B3AH/AYABvQHcAf8BjwHTAfUB/wGPAdMB9QH/AZUB2QH4Af8C9QHuAf8BRAFTAVsBlwQAAkIBQQFy
|
||||
AvgB7gL/AcwBQgH/Af4BywFBAf8B7AHSAYYB/wLaAckB/wLYAccB/wLdAc4B/wLUAcMB/wLTAcIB/wLZ
|
||||
AcoB/wLPAb4B/wLOAb0B/wLNAbwB/wL4Ae4B/wJCAUEBcgJIAUABcgL4Ae4B/wHsAYYBYwH/AeIBewFZ
|
||||
Af8B1AFuAUwB/wHEAWABPgH/AbYBUgEwAf8BrQFHASUB/wGrAUMBIQH/AbEBRAEiAf8BvQFKASgB/wHM
|
||||
AVIBMAH/AdsBWgE4Af8B6AFiAUAB/wL4Ae4B/wJIAUABcgJCAUEBcgL4Ae4C/wHMAUIB/wH+AcsBQQH/
|
||||
AewB0gGGAf8C2gHJAf8C2AHHAf8BrQFCASAB/wHeAbYBngH/Ad4BtQGdAf8BrQFCASAB/wLPAb4B/wLO
|
||||
Ab0B/wLNAbwB/wL4Ae4B/wJCAUEBcggAAUQBUwFaAZQBmwHhAfcB/wGUAdsB9AH/AZQB2wH0Af8BmwHh
|
||||
AfcB/wEuAY0BvAH/AYEBvgHdAf8BgQG+Ad0B/wGQAdQB9gH/AZAB1AH2Af8BlwHbAfkB/wL+Af0B/wFE
|
||||
AVMBWgGUBAACQQFAAXAC+QHxAv8BzAFCAv8B7gGIAf8B7AHSAYYB/wL5AfUB/wL5AfUB/wLWAcUB/wL5
|
||||
AfUB/wL5AfUB/wLRAcAB/wL5AfUB/wL5AfUB/wLNAbwB/wL5AfEB/wJBAUABcAJHAUABcAL5AfEB/wHs
|
||||
AYYBYwH/AfgBxQF5Af8B7QG1AXgB/wH1AcwBvAH/AfUBzAG8Af8B4AG3AZ8B/wH1AcwBvAH/AfUBzAG8
|
||||
Af8B3QG0AZwB/wH1AcwBvAH/AfUBzAG8Af8B6AFiAUAB/wL5AfEB/wJHAUABcAJBAUABcAL5AfEC/wHM
|
||||
AUIC/wHuAYgB/wHsAdIBhgH/AvkB9QH/AvkB9QH/AasBRAEiAf8B9QHMAbwB/wH1AcwBvAH/AasBRAEi
|
||||
Af8C+QH1Af8C+QH1Af8CzQG8Af8C+QHxAf8CQQFAAXAIAAFEAVEBVwGQAZ4B5QH5Af8BmAHfAfYB/wGY
|
||||
Ad8B9gH/AZ4B5QH5Af8BMAGQAcAB/wGDAcAB3wH/AYMBwAHfAf8BkgHWAfgB/wGSAdYB+AH/AZkB3QH6
|
||||
Af8BRAFRAVcBkAMjATMEAAJBAUABbgL7AfQC/wHMAUIB/wH+AcsBQQH/AewB0gGGAf8C2gHJAf8C2AHH
|
||||
Af8C3gHQAf8C1AHDAf8C0wHCAf8C2gHMAf8CzwG+Af8CzgG9Af8CzQG8Af8C+wH0Af8CQQFAAW4CRwFA
|
||||
AW4C+wH0Af8B7AGGAWMB/wHiAXsBWQH/AdQBbgFMAf8BxAFgAT4B/wG2AVIBMAH/Aa0BRwElAf8BqwFD
|
||||
ASEB/wGxAUQBIgH/Ab0BSgEoAf8BzAFSATAB/wHbAVoBOAH/AegBYgFAAf8C+wH0Af8CRwFAAW4CQQFA
|
||||
AW4C+wH0Av8BzAFCAf8B/gHLAUEB/wHsAdIBhgH/AtoByQH/AtgBxwH/AbIBTAEqAf8B3gG2AZ4B/wHe
|
||||
AbUBnQH/AbIBTAEqAf8CzwG+Af8CzgG9Af8CzQG8Af8C+wH0Af8CQQFAAW4IAAFDAU8BVQGNAaMB6AH7
|
||||
Af8BnQHjAfkB/wGdAeMB+QH/AaMB6AH7Af8BMwGUAcUB/wGFAcIB4QH/AYUBwgHhAf8BlAHYAfoB/wGU
|
||||
AdgB+gH/AZsB3wH8Af8BQwFPAVUBjQgAAkABPwFtAvwB9wL/AcwBQgL/Ae4BiAH/AewB0gGGAf8C/AH6
|
||||
Af8C/AH6Af8C1gHFAf8C/AH6Af8C/AH6Af8C0QHAAf8C/AH6Af8C/AH6Af8CzQG8Af8C/AH3Af8CQAE/
|
||||
AW0CRwFAAW0C/AH3Av8BzAFDAv8B7gGIAf8B7AHSAYYB/wL8AfoB/wL8AfoB/wLWAcUB/wL8AfoB/wL8
|
||||
AfoB/wLRAcAB/wL8AfoB/wL8AfoB/wLNAbwB/wL8AfcB/wJHAUABbQJAAT8BbQL8AfcC/wHMAUIC/wHu
|
||||
AYgB/wHsAdIBhgH/AvwB+gH/AvwB+gH/AcABWgE4Af8B9gHOAb8B/wH2Ac4BvwH/AcABWgE4Af8C/AH6
|
||||
Af8C/AH6Af8CzQG8Af8C/AH3Af8CQAE/AW0IAAFDAU8BVAGKAaYB6wH8Af8BoQHmAfsB/wGhAeYB+wH/
|
||||
AaYB6wH8Af8BOgGdAc8B/wGHAcQB4gH/AYcBxAHiAf8BlgHaAfwB/wGWAdoB/AH/AZ4B4gH9Af8BQwFP
|
||||
AVQBiggAAj8BPgFrAv0B+QL/AcwBQgH/Af4BywFBAf8B9QHOAWIB/wHrAdIBhQH/AekB0AGDAf8B5wHO
|
||||
AYEB/wHlAcwBgAH/AeQBywF8Af8B4gHJAXoB/wHgAccBeAH/Ad8BxgF3Af8B3gHFAXYB/wL9AfkB/wI/
|
||||
AT4BawJHAUABawL9AfkC/wHMAUMB/wH+AcsBQgH/AfUBzgFjAf8B6wHSAYUB/wHpAdABgwH/AecBzgGB
|
||||
Af8B5QHMAYAB/wHkAcsBfQH/AeIByQF7Af8B4AHHAXkB/wHfAcYBeAH/Ad4BxQF3Af8C/QH5Af8CRwFA
|
||||
AWsCPwE+AWsC/QH5Av8BzAFCAf8B/gHLAUEB/wH1Ac4BYgH/AesB0gGFAf8B6QHQAYMB/wHRAWoBSAH/
|
||||
AekBsQF0Af8B6AGwAXMB/wHRAWoBSAH/AeABxwF4Af8B3wHGAXcB/wHeAcUBdgH/Av0B+QH/Aj8BPgFr
|
||||
CAABQgFNAVIBhwGpAe4B/QH/AaQB6QH8Af8BpAHpAfwB/wGqAe8B/QH/AUABoQHRAf8BkAHRAfEB/wGW
|
||||
AdoB+wH/AZcB2wH9Af8BlwHbAf0B/wGfAeMB/gH/AUIBTQFSAYcIAAI/AT4BagL+AfwC/wHMAUIC/wHu
|
||||
AYgB/wH9AcoBQAH/AfwB6wGFAf8B+wHqAYQB/wH4AcUBOwH/AfYB5QF9Af8B9AHjAXsB/wHzAcABNgH/
|
||||
AfEB4AF4Af8B7wHeAXYB/wHvAbwBMgH/Av4B/AH/Aj8BPgFqAkcBQAFqAv4B/AL/AcwBQwL/Ae4BiAH/
|
||||
Af0BygFBAf8B/AHrAYUB/wH7AeoBhAH/AfgBxQE8Af8B9gHlAX4B/wH0AeMBfAH/AfMBwAE3Af8B8QHg
|
||||
AXkB/wHvAd4BdwH/Ae8BvAEzAf8C/gH8Af8CRwFAAWoCPwE+AWoC/gH8Av8BzAFCAv8B7gGIAf8B/QHK
|
||||
AUAB/wH8AesBhQH/AfsB6gGEAf8B4QF5AVcB/wHzAcABcwH/AfIBvwFyAf8B4QF5AVcB/wHxAeABeAH/
|
||||
Ae8B3gF2Af8B7wG8ATIB/wL+AfwB/wI/AT4BaggAAUMBTAFSAYUBrQHxAv8BqwHvAf4B/wGVAeIB+AH/
|
||||
AWwByQHtAf8BRgGpAdkB/wGYAdwB/gH/AZgB3AH+Af8BmAHcAf4B/wGYAdwB/gH/AaEB5QL/AUMBTAFS
|
||||
AYUIAAI+AT0BaAL/Af4C/wHMAUIB/wH+AcsBQQH/Af0BygFAAf8B/AHJAT8B/wH6AccBPQH/AfgBxQE7
|
||||
Af8B9gHDAToB/wH1AcIBOAH/AfMBwAE2Af8B8QG+ATQB/wHwAb0BMwH/Ae8BvAEyA/8B/gH/Aj4BPQFo
|
||||
AkcBQAFoAv8B/gL/AcwBQwH/Af4BywFCAf8B/QHKAUEB/wH8AckBQAH/AfoBxwE+Af8B+AHFATwB/wH2
|
||||
AcMBOwH/AfUBwgE5Af8B8wHAATcB/wHxAb4BNQH/AfABvQE0Af8B7wG8ATMD/wH+Af8CRwFAAWgCPgE9
|
||||
AWgC/wH+Av8BzAFCAf8B/gHLAUEB/wH9AcoBQAH/AfwByQE/Af8B+gHHAT0B/wHsAYYBYgH/AewBhgFi
|
||||
Af8B7AGGAWIB/wHsAYYBYgH/AfEBvgE0Af8B8AG9ATMB/wHvAbwBMgP/Af4B/wI+AT0BaAgAAUMBTAFQ
|
||||
AYMBiAHcAfQB/wFeAcAB6QH/AV0BvwHqAf8BgAHTAfQB/wGcAeMB/QH/AaIB5gL/AaIB5gL/AaIB5gL/
|
||||
AaIB5gL/AaYB6gL/AUMBTAFQAYMIAAI+AT0BZzj/Aj4BPQFnAkcBQAFnOP8CRwFAAWcCPgE9AWc4/wI+
|
||||
AT0BZwgAATkBOwE9AWEBQgFLAU8BgQFCAUsBTwGBAUIBSwFPAYEBQgFLAU8BgQFCAUsBTwGBAUIBSwFP
|
||||
AYEBQgFLAU8BgQFCAUsBTwGBAUIBSwFPAYEBQgFLAU8BgQE5ATsBPQFhCAADMQFNAj4BPQFmAj4BPQFm
|
||||
Aj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFmAj4BPQFm
|
||||
Aj4BPQFmAj4BPQFmAzEBTQI3ATQBTQJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJH
|
||||
AUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgJHAUABZgI3ATQBTQMxAU0CPgE9
|
||||
AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9AWYCPgE9
|
||||
AWYCPgE9AWYCPgE9AWYCPgE9AWYDMQFNAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYA
|
||||
A/8RAAGAAf8BgAEBBQABfwEAAQEFAAE/AQABAQUAAR8BAAEBBAABgAEPAYABAQQAAcABBwHAAQMEAAHg
|
||||
AQMB4AEDBAAB8AEBAfABAQQAAfgBAAH4BQAB/AEAAfwFAAH+AQgB/gEIBAAB/wEAAf8FAAH/AYAB/wGA
|
||||
BAAB/wHAAf8BwAQAAfgBfwYAAeABPxYAAcABAQYAAcABAQYAAcABAQYAAcABAQYAAcABAQYAAcABAQYA
|
||||
AcABAwYAAcABAwYAAcABAwYAAcABAwYAAcABAwYAAcABAwYACw==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="toolStripMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>211, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="toolbuttonOpenMib.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAK6SURBVDhPjZNbSNNRHMfPU9DtwR71oZf5IgkF0YMEEYb2
|
||||
EGgG5YNgGQmGSUoYimbel5KKmlM0u3jJSpv3ad7WnGkzb2yO4bByF3WuuTnnnLv47Zw/9YclQQc+/L//
|
||||
P+d8/r/f+Z8/Ib/HjJDcmhaS3P+Bzf2zjr8qiki+QyuE6dNNbIzFw6F8DJ++AVh97c9GK9jcA4LJAlKI
|
||||
rQ7sW9/DpauGZSoFg6JwfJSU+TE0XIXOgqCaAwJ5ASn2bb6F19TM4bO+w4z4HgwWC9YcDugpK3Y7umQy
|
||||
FOZEDMRkZQX7SWS5pMRrboVn9RUHy1/aEqDSajGn0WDZbIZ6bQ0t/f1gIzojI8lPMvaIPPWsN2FP/5yD
|
||||
ZdmLWLwUi/FhZASSqSlOUtXczBMcGZnFVzGUTSr2jI1wfq/lYHms4Tqkc3MYnZ2F0mDAqs3GV8LaiUhN
|
||||
TeYFA5mkenelHg5tNQfLw3UxaOrpQZdUiu7xca5/Mc0do6PQb28jPDk5hRf0PiQi5zcR7JoKDpYHaqIg
|
||||
VyohW1jg+lcZjVwlCzod1p1OXEhMvM8LOtNJvWOpEjZVKQfL/ZVX0NrXh165HP2Tk5hQqzGuUmFQocCm
|
||||
y4XzCQlpvKA9jTTa1WWwzBdzsNxdfhmfFxcxQRct0Q3UmEzY2t2FdWcHdrcb5+LiHvCC1hTSbFOWwDyT
|
||||
x8GyuDQCbRIJ3tBPp6CfU0pbcdA3M4mDCs7ExqYzwWHKibo7pNs6T4+yIofDSqtof3IJBtqzTq+Hx+uF
|
||||
y+OBky5kkh2aT0VFZTNBAEWQFEFqhyvO2pclSe6f03nYnC1EW9FFGOnGGSi+/X14KW6fD3tUtkdzYFiY
|
||||
0O801iWSaNFtUteWGST92nL1R/q1Q7ojAkHV0ZCQkuOhocV/c0wguHvgn2APyuPJ6dI4kpV/gzyjtycp
|
||||
gf8g4Begs1B6Kbj3cQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="dialogOpenMib.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>337, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{86CC0B65-7985-4017-A252-0A7A18DCAEF3}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>LwipMibViewer</RootNamespace>
|
||||
<AssemblyName>LwipMibViewer</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FormMain.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormMain.Designer.cs">
|
||||
<DependentUpon>FormMain.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="FormMain.resx">
|
||||
<DependentUpon>FormMain.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SharpSnmpLib\SharpSnmpLib.Mib.csproj">
|
||||
<Project>{CBE20411-5DB7-487D-825D-7694267BB6F5}</Project>
|
||||
<Name>SharpSnmpLib.Mib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace LwipMibViewer
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// Der Haupteinstiegspunkt für die Anwendung.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new FormMain());
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die mit einer Assembly verknüpft sind.
|
||||
[assembly: AssemblyTitle("LwipMibViewer")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("LwipMibViewer")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("7ffbd1c1-1c64-45bb-b243-2400446c649d")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
Generated
+63
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
// Laufzeitversion:4.0.30319.225
|
||||
//
|
||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
// der Code erneut generiert wird.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace LwipMibViewer.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
/// </summary>
|
||||
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LwipMibViewer.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Generated
+26
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
// Laufzeitversion:4.0.30319.225
|
||||
//
|
||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
// der Code erneut generiert wird.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace LwipMibViewer.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace LwipSnmpCodeGeneration
|
||||
{
|
||||
public interface IRestriction
|
||||
{
|
||||
string GetCheckCodeValid(string varNameToCheck);
|
||||
string GetCheckCodeInvalid(string varNameToCheck);
|
||||
}
|
||||
|
||||
public class BitMaskRestriction : IRestriction
|
||||
{
|
||||
UInt32 mask;
|
||||
|
||||
public BitMaskRestriction(UInt32 mask)
|
||||
{
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
public string GetCheckCodeValid(string varNameToCheck)
|
||||
{
|
||||
return String.Format("(({0} & {1}) == {0})", varNameToCheck, this.mask);
|
||||
}
|
||||
|
||||
public string GetCheckCodeInvalid(string varNameToCheck)
|
||||
{
|
||||
return String.Format("(({0} & {1}) != {0})", varNameToCheck, this.mask);
|
||||
}
|
||||
}
|
||||
|
||||
public class IsEqualRestriction : IRestriction
|
||||
{
|
||||
private Int64 value;
|
||||
|
||||
public IsEqualRestriction(Int64 value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long Value
|
||||
{
|
||||
get { return value; }
|
||||
}
|
||||
|
||||
public string GetCheckCodeValid(string varNameToCheck)
|
||||
{
|
||||
return String.Format("({0} == {1})", varNameToCheck, this.value);
|
||||
}
|
||||
|
||||
public string GetCheckCodeInvalid(string varNameToCheck)
|
||||
{
|
||||
return String.Format("({0} != {1})", varNameToCheck, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
public class IsInRangeRestriction : IRestriction
|
||||
{
|
||||
private Int64 rangeStart;
|
||||
private Int64 rangeEnd;
|
||||
|
||||
public IsInRangeRestriction(Int64 rangeStart, Int64 rangeEnd)
|
||||
{
|
||||
this.rangeStart = rangeStart;
|
||||
this.rangeEnd = rangeEnd;
|
||||
}
|
||||
|
||||
public long RangeStart
|
||||
{
|
||||
get { return this.rangeStart; }
|
||||
}
|
||||
|
||||
public long RangeEnd
|
||||
{
|
||||
get { return this.rangeEnd; }
|
||||
}
|
||||
|
||||
public string GetCheckCodeValid(string varNameToCheck)
|
||||
{
|
||||
return String.Format("(({0} >= {1}) && ({0} <= {2}))", varNameToCheck, this.rangeStart, this.rangeEnd);
|
||||
}
|
||||
|
||||
public string GetCheckCodeInvalid(string varNameToCheck)
|
||||
{
|
||||
return String.Format("(({0} < {1}) || ({0} > {2}))", varNameToCheck, this.rangeStart, this.rangeEnd);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace LwipSnmpCodeGeneration
|
||||
{
|
||||
public static class LwipOpts
|
||||
{
|
||||
public static bool GenerateEmptyFolders = false;
|
||||
/// <summary>
|
||||
/// If a tree node only has scalar nodes as child nodes, it is replaced by
|
||||
/// a single scalar array node in order to save memory and have only one single get/test/set method for all scalars.
|
||||
/// </summary>
|
||||
public static bool GenerateScalarArrays = true;
|
||||
/// <summary>
|
||||
/// If a tree node has multiple scalars as subnodes as well as other treenodes it
|
||||
/// defines a single get/test/set method for all scalar child node.
|
||||
/// (without other treenodes as child it would have been converted to scalar array node).
|
||||
/// </summary>
|
||||
public static bool GenerateSingleAccessMethodsForTreeNodeScalars = GenerateScalarArrays;
|
||||
}
|
||||
|
||||
public static class LwipDefs
|
||||
{
|
||||
public const string Null = "NULL";
|
||||
public const string Vt_U8 = "u8_t";
|
||||
public const string Vt_U16 = "u16_t";
|
||||
public const string Vt_U32 = "u32_t";
|
||||
public const string Vt_S8 = "s8_t";
|
||||
public const string Vt_S16 = "s16_t";
|
||||
public const string Vt_S32 = "s32_t";
|
||||
public const string Vt_Snmp_err = "snmp_err_t";
|
||||
|
||||
public const string Incl_SnmpOpts = "lwip/apps/snmp_opts.h";
|
||||
public const string Opt_SnmpEnabled = "LWIP_SNMP";
|
||||
|
||||
public const string Vt_StMib = "struct snmp_mib";
|
||||
public const string Vt_StObjectId = "struct snmp_obj_id";
|
||||
public const string Vt_StNode = "struct snmp_node";
|
||||
public const string Vt_StNodeInstance = "struct snmp_node_instance";
|
||||
public const string Vt_StTreeNode = "struct snmp_tree_node";
|
||||
public const string Vt_StScalarNode = "struct snmp_scalar_node";
|
||||
public const string Vt_StScalarArrayNode = "struct snmp_scalar_array_node";
|
||||
public const string Vt_StScalarArrayNodeDef = "struct snmp_scalar_array_node_def";
|
||||
public const string Vt_StTableNode = "struct snmp_table_node";
|
||||
public const string Vt_StTableColumnDef = "struct snmp_table_col_def";
|
||||
public const string Vt_StNextOidState = "struct snmp_next_oid_state";
|
||||
|
||||
public const string Def_NodeAccessReadOnly = "SNMP_NODE_INSTANCE_READ_ONLY";
|
||||
public const string Def_NodeAccessReadWrite = "SNMP_NODE_INSTANCE_READ_WRITE";
|
||||
public const string Def_NodeAccessWriteOnly = "SNMP_NODE_INSTANCE_WRITE_ONLY";
|
||||
public const string Def_NodeAccessNotAccessible = "SNMP_NODE_INSTANCE_NOT_ACCESSIBLE";
|
||||
|
||||
public const string Def_ErrorCode_Ok = "SNMP_ERR_NOERROR";
|
||||
public const string Def_ErrorCode_WrongValue = "SNMP_ERR_WRONGVALUE";
|
||||
public const string Def_ErrorCode_NoSuchInstance = "SNMP_ERR_NOSUCHINSTANCE";
|
||||
|
||||
public const string FnctSuffix_GetValue = "_get_value";
|
||||
public const string FnctSuffix_SetTest = "_set_test";
|
||||
public const string FnctSuffix_SetValue = "_set_value";
|
||||
public const string FnctSuffix_GetInstance = "_get_instance";
|
||||
public const string FnctSuffix_GetNextInstance = "_get_next_instance";
|
||||
|
||||
public const string FnctName_SetTest_Ok = "snmp_set_test_ok";
|
||||
|
||||
public static string GetLwipDefForSnmpAccessMode(SnmpAccessMode am)
|
||||
{
|
||||
switch (am)
|
||||
{
|
||||
case SnmpAccessMode.ReadOnly: return Def_NodeAccessReadOnly;
|
||||
case SnmpAccessMode.ReadWrite: return Def_NodeAccessReadWrite;
|
||||
case SnmpAccessMode.NotAccessible: return Def_NodeAccessNotAccessible;
|
||||
case SnmpAccessMode.WriteOnly: return Def_NodeAccessWriteOnly;
|
||||
default: throw new NotSupportedException("Unknown SnmpAccessMode!");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetAsn1DefForSnmpDataType(SnmpDataType dt)
|
||||
{
|
||||
switch (dt)
|
||||
{
|
||||
// primitive
|
||||
case SnmpDataType.Null:
|
||||
return "SNMP_ASN1_TYPE_NULL";
|
||||
case SnmpDataType.Bits:
|
||||
case SnmpDataType.OctetString:
|
||||
return "SNMP_ASN1_TYPE_OCTET_STRING";
|
||||
case SnmpDataType.ObjectIdentifier:
|
||||
return "SNMP_ASN1_TYPE_OBJECT_ID";
|
||||
case SnmpDataType.Integer:
|
||||
return "SNMP_ASN1_TYPE_INTEGER";
|
||||
|
||||
// application
|
||||
case SnmpDataType.IpAddress:
|
||||
return "SNMP_ASN1_TYPE_IPADDR";
|
||||
case SnmpDataType.Counter:
|
||||
return "SNMP_ASN1_TYPE_COUNTER";
|
||||
case SnmpDataType.Gauge:
|
||||
return "SNMP_ASN1_TYPE_GAUGE";
|
||||
case SnmpDataType.TimeTicks:
|
||||
return "SNMP_ASN1_TYPE_TIMETICKS";
|
||||
case SnmpDataType.Opaque:
|
||||
return "SNMP_ASN1_TYPE_OPAQUE";
|
||||
case SnmpDataType.Counter64:
|
||||
return "SNMP_ASN1_TYPE_COUNTER64";
|
||||
default:
|
||||
throw new NotSupportedException("Unknown SnmpDataType!");
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetLengthForSnmpDataType(SnmpDataType dt)
|
||||
{
|
||||
switch (dt)
|
||||
{
|
||||
case SnmpDataType.Null:
|
||||
return "0";
|
||||
|
||||
case SnmpDataType.Integer:
|
||||
case SnmpDataType.Counter:
|
||||
case SnmpDataType.IpAddress:
|
||||
case SnmpDataType.Gauge:
|
||||
case SnmpDataType.TimeTicks:
|
||||
return "4";
|
||||
|
||||
case SnmpDataType.Counter64:
|
||||
return "8";
|
||||
|
||||
case SnmpDataType.OctetString:
|
||||
case SnmpDataType.ObjectIdentifier:
|
||||
case SnmpDataType.Bits:
|
||||
case SnmpDataType.Opaque:
|
||||
return null;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException("Unknown SnmpDataType!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum SnmpDataType
|
||||
{
|
||||
Null,
|
||||
|
||||
Integer, // INTEGER, Integer32
|
||||
|
||||
Counter, // Counter, Counter32
|
||||
Gauge, // Gauge, Gauge32, Unsigned32
|
||||
TimeTicks,
|
||||
|
||||
Counter64,
|
||||
|
||||
OctetString,
|
||||
Opaque,
|
||||
Bits,
|
||||
|
||||
ObjectIdentifier,
|
||||
|
||||
IpAddress,
|
||||
}
|
||||
|
||||
public enum SnmpAccessMode
|
||||
{
|
||||
ReadOnly,
|
||||
ReadWrite,
|
||||
WriteOnly,
|
||||
NotAccessible
|
||||
}
|
||||
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{AABCAB90-1540-45D4-A159-14831A54E9A3}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>LwipSnmpCodeGeneration</RootNamespace>
|
||||
<AssemblyName>LwipSnmpCodeGeneration</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="IRestriction.cs" />
|
||||
<Compile Include="SnmpScalarNodeCounter64.cs" />
|
||||
<Compile Include="SnmpScalarNodeTruthValue.cs" />
|
||||
<Compile Include="SnmpScalarAggregationNode.cs" />
|
||||
<Compile Include="SnmpTableNode.cs" />
|
||||
<Compile Include="SnmpScalarArrayNode.cs" />
|
||||
<Compile Include="MibHeaderFile.cs" />
|
||||
<Compile Include="SnmpScalarNodeBits.cs" />
|
||||
<Compile Include="SnmpMib.cs" />
|
||||
<Compile Include="SnmpScalarNodeInt.cs" />
|
||||
<Compile Include="SnmpScalarNodeObjectIdentifier.cs" />
|
||||
<Compile Include="SnmpScalarNodeOctetString.cs" />
|
||||
<Compile Include="SnmpScalarNodeUint.cs" />
|
||||
<Compile Include="SnmpTreeNode.cs" />
|
||||
<Compile Include="LwipSnmp.cs" />
|
||||
<Compile Include="MibCFile.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SnmpNode.cs" />
|
||||
<Compile Include="SnmpScalarNode.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CCodeGeneration\CCodeGeneration.csproj">
|
||||
<Project>{7DA7C0AB-0982-4BF5-9324-F59A7A08D65B}</Project>
|
||||
<Name>CCodeGeneration</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using CCodeGeneration;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace LwipSnmpCodeGeneration
|
||||
{
|
||||
public class MibCFile
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private const string PreservedSectionMarker = "LWIP MIB generator - preserved section begin";
|
||||
private const string PreservedSectionHeader =
|
||||
"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" +
|
||||
PreservedSectionMarker + "\n" +
|
||||
"Code below is preserved on regeneration. Remove these comment lines to regenerate code.\n" +
|
||||
"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
|
||||
|
||||
private readonly List<CodeElement> includes = new List<CodeElement>();
|
||||
private readonly List<CodeElement> defines = new List<CodeElement>();
|
||||
private readonly List<CodeElement> declarations = new List<CodeElement>();
|
||||
private readonly List<CodeElement> implementation = new List<CodeElement>();
|
||||
private readonly List<CodeElement> preservedCode = new List<CodeElement>();
|
||||
|
||||
#endregion
|
||||
|
||||
public MibCFile()
|
||||
{
|
||||
}
|
||||
|
||||
#region Accessors
|
||||
|
||||
public List<CodeElement> Includes
|
||||
{
|
||||
get { return this.includes; }
|
||||
}
|
||||
|
||||
public List<CodeElement> Defines
|
||||
{
|
||||
get { return this.defines; }
|
||||
}
|
||||
|
||||
public List<CodeElement> Declarations
|
||||
{
|
||||
get { return this.declarations; }
|
||||
}
|
||||
|
||||
public List<CodeElement> Implementation
|
||||
{
|
||||
get { return this.implementation; }
|
||||
}
|
||||
|
||||
public List<CodeElement> PreservedCode
|
||||
{
|
||||
get { return this.preservedCode; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Save(CGenerator cGenerator)
|
||||
{
|
||||
CFile cFile = new CFile();
|
||||
|
||||
cFile.AddElement(new Comment("Generated by LwipMibCompiler"));
|
||||
cFile.AddElement(EmptyLine.SingleLine);
|
||||
|
||||
cFile.AddElement(new PP_Include(LwipDefs.Incl_SnmpOpts));
|
||||
CodeContainerBase e = cFile.AddElement(new PP_If(LwipDefs.Opt_SnmpEnabled)) as CodeContainerBase;
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
|
||||
// include header file
|
||||
string file = cGenerator.FileName;
|
||||
if (!String.IsNullOrWhiteSpace(file))
|
||||
{
|
||||
string ext = System.IO.Path.GetExtension(file);
|
||||
|
||||
string headerFile = !String.IsNullOrEmpty(ext) ? file.Substring(0, file.Length - ext.Length) : file;
|
||||
headerFile += ".h";
|
||||
|
||||
e.AddElement(new PP_Include(headerFile));
|
||||
}
|
||||
|
||||
// include common snmp files
|
||||
e.AddElement(new PP_Include("lwip/apps/snmp.h"));
|
||||
e.AddElement(new PP_Include("lwip/apps/snmp_core.h"));
|
||||
e.AddElement(new PP_Include("lwip/apps/snmp_scalar.h"));
|
||||
e.AddElement(new PP_Include("lwip/apps/snmp_table.h"));
|
||||
|
||||
if (this.includes.Count > 0)
|
||||
{
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
e.AddElements(this.includes);
|
||||
}
|
||||
|
||||
if (this.defines.Count > 0)
|
||||
{
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
e.AddElements(this.defines);
|
||||
}
|
||||
|
||||
if (this.declarations.Count > 0)
|
||||
{
|
||||
e.AddElement(EmptyLine.TwoLines);
|
||||
e.AddElements(this.declarations);
|
||||
}
|
||||
|
||||
if (this.implementation.Count > 0)
|
||||
{
|
||||
e.AddElement(EmptyLine.TwoLines);
|
||||
e.AddElements(this.implementation);
|
||||
}
|
||||
|
||||
if (this.preservedCode.Count > 0)
|
||||
{
|
||||
e.AddElement(EmptyLine.TwoLines);
|
||||
e.AddElement(new Comment(PreservedSectionHeader));
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
e.AddElements(this.preservedCode);
|
||||
}
|
||||
|
||||
cFile.Save(cGenerator);
|
||||
}
|
||||
|
||||
public static string GetPreservedCode(string file)
|
||||
{
|
||||
if (File.Exists(file))
|
||||
{
|
||||
using (StreamReader fileStream = new StreamReader(file))
|
||||
{
|
||||
while (!fileStream.EndOfStream)
|
||||
{
|
||||
string line = fileStream.ReadLine();
|
||||
if (line == PreservedSectionMarker)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileStream.EndOfStream)
|
||||
{
|
||||
// skip the rest of the comment + spacer line
|
||||
fileStream.ReadLine(); // "Code below is preserved...
|
||||
fileStream.ReadLine(); // "+++++++++++++++++++++++...
|
||||
fileStream.ReadLine(); // */
|
||||
fileStream.ReadLine(); //
|
||||
|
||||
string preservedCode = fileStream.ReadToEnd();
|
||||
|
||||
int lastEndif = preservedCode.LastIndexOf("#endif", StringComparison.Ordinal);
|
||||
preservedCode = preservedCode.Remove(lastEndif);
|
||||
|
||||
return preservedCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using CCodeGeneration;
|
||||
|
||||
namespace LwipSnmpCodeGeneration
|
||||
{
|
||||
public class MibHeaderFile
|
||||
{
|
||||
|
||||
#region Fields
|
||||
|
||||
private readonly List<CodeElement> defines = new List<CodeElement>();
|
||||
private readonly List<CodeElement> includes = new List<CodeElement>();
|
||||
private readonly List<CodeElement> functionDeclarations = new List<CodeElement>();
|
||||
private readonly List<CodeElement> variableDeclarations = new List<CodeElement>();
|
||||
|
||||
#endregion
|
||||
|
||||
public MibHeaderFile()
|
||||
{
|
||||
}
|
||||
|
||||
#region Accessors
|
||||
|
||||
public List<CodeElement> Defines
|
||||
{
|
||||
get { return this.defines; }
|
||||
}
|
||||
|
||||
public List<CodeElement> Includes
|
||||
{
|
||||
get { return this.includes; }
|
||||
}
|
||||
|
||||
public List<CodeElement> FunctionDeclarations
|
||||
{
|
||||
get { return this.functionDeclarations; }
|
||||
}
|
||||
|
||||
public List<CodeElement> VariableDeclarations
|
||||
{
|
||||
get { return this.variableDeclarations; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Save(CGenerator cGenerator)
|
||||
{
|
||||
CFile cFile = new CFile();
|
||||
|
||||
cFile.AddElement(new Comment("Generated by LwipMibCompiler"));
|
||||
cFile.AddElement(EmptyLine.SingleLine);
|
||||
|
||||
string headerDefine = cGenerator.FileName;
|
||||
headerDefine = new Regex("[^a-zA-Z0-9]").Replace(headerDefine, "_");
|
||||
headerDefine = headerDefine.ToUpperInvariant();
|
||||
|
||||
CodeContainerBase e = cFile.AddElement(new PP_Ifdef(headerDefine, inverted: true)) as CodeContainerBase;
|
||||
e.AddElement(new PP_Macro(headerDefine, headerDefine));
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
|
||||
e.AddElement(new PP_Include(LwipDefs.Incl_SnmpOpts));
|
||||
e = e.AddElement(new PP_If(LwipDefs.Opt_SnmpEnabled)) as CodeContainerBase;
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
|
||||
CodeContainerBase cplusplusopen = e.AddElement(new PP_Ifdef("__cplusplus")) as CodeContainerBase;
|
||||
cplusplusopen.AddElement(new Code("extern \"C\" {"));
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
|
||||
if (this.includes.Count > 0)
|
||||
{
|
||||
e.AddElements(this.includes);
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
}
|
||||
|
||||
if (this.defines.Count > 0)
|
||||
{
|
||||
e.AddElements(this.defines);
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
}
|
||||
|
||||
e.AddElements(this.functionDeclarations, EmptyLine.SingleLine);
|
||||
e.AddElements(this.variableDeclarations, EmptyLine.SingleLine);
|
||||
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
CodeContainerBase cplusplusclose = e.AddElement(new PP_Ifdef("__cplusplus")) as CodeContainerBase;
|
||||
cplusplusclose.AddElement(new Code("}"));
|
||||
|
||||
e.AddElement(EmptyLine.SingleLine);
|
||||
cFile.Save(cGenerator);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die mit einer Assembly verknüpft sind.
|
||||
[assembly: AssemblyTitle("LwipSnmpCodeGeneration")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("LwipSnmpCodeGeneration")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("8cfbbb8b-dfbb-4dd5-80c9-e07845dd58c9")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using CCodeGeneration;
|
||||
|
||||
namespace LwipSnmpCodeGeneration
|
||||
{
|
||||
public class SnmpMib : SnmpTreeNode
|
||||
{
|
||||
public uint[] BaseOid { get; set; }
|
||||
|
||||
public SnmpMib()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public SnmpMib(uint[] baseOid)
|
||||
: base(null)
|
||||
{
|
||||
this.BaseOid = baseOid;
|
||||
}
|
||||
|
||||
public override string FullNodeName
|
||||
{
|
||||
get { return this.Name + "_root"; }
|
||||
}
|
||||
|
||||
public override void GenerateCode(MibCFile mibFile)
|
||||
{
|
||||
base.GenerateCode(mibFile);
|
||||
|
||||
System.Diagnostics.Debug.Assert((this.BaseOid != null) && (this.BaseOid.Length > 0));
|
||||
|
||||
// create and add BaseOID declarations
|
||||
StringBuilder boidInitialization = new StringBuilder("{");
|
||||
foreach (uint t in this.BaseOid)
|
||||
{
|
||||
boidInitialization.Append(t);
|
||||
boidInitialization.Append(",");
|
||||
}
|
||||
boidInitialization.Length -= 1;
|
||||
boidInitialization.Append("}");
|
||||
|
||||
VariableDeclaration boidDecl = new VariableDeclaration(
|
||||
new VariableType(this.Name + "_base_oid", LwipDefs.Vt_U32, null, ConstType.Value, String.Empty),
|
||||
boidInitialization.ToString(), true);
|
||||
|
||||
mibFile.Declarations.Add(boidDecl);
|
||||
mibFile.Declarations.Add(GetExportDeclaration());
|
||||
}
|
||||
|
||||
public override void GenerateHeaderCode(MibHeaderFile mibHeaderFile)
|
||||
{
|
||||
mibHeaderFile.Includes.Add(new PP_Include("lwip/apps/snmp_core.h"));
|
||||
|
||||
mibHeaderFile.VariableDeclarations.Add(VariablePrototype.FromVariableDeclaration(GetExportDeclaration()));
|
||||
}
|
||||
|
||||
VariableDeclaration GetExportDeclaration()
|
||||
{
|
||||
return new VariableDeclaration(
|
||||
new VariableType(this.Name, LwipDefs.Vt_StMib, null, ConstType.Value),
|
||||
String.Format("{{{0}_base_oid, LWIP_ARRAYSIZE({0}_base_oid), &{1}.node}}", this.Name, this.FullNodeName));
|
||||
}
|
||||
}
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Martin Hentschel <info@cl-soft.de>
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using CCodeGeneration;
|
||||
|
||||
namespace LwipSnmpCodeGeneration
|
||||
{
|
||||
public abstract class SnmpNode
|
||||
{
|
||||
public static readonly Regex NameValidationRegex = new Regex(@"^\w+$");
|
||||
|
||||
private string name;
|
||||
private readonly SnmpTreeNode parentNode;
|
||||
|
||||
protected SnmpNode(SnmpTreeNode parentNode)
|
||||
{
|
||||
this.parentNode = parentNode;
|
||||
}
|
||||
|
||||
public SnmpTreeNode ParentNode
|
||||
{
|
||||
get { return this.parentNode; }
|
||||
}
|
||||
|
||||
public virtual uint Oid { get; set; }
|
||||
|
||||
public abstract string FullNodeName
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public virtual string Name
|
||||
{
|
||||
get { return this.name; }
|
||||
set
|
||||
{
|
||||
if (value != this.name)
|
||||
{
|
||||
// check for valid name
|
||||
if (!NameValidationRegex.IsMatch(value))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Name");
|
||||
}
|
||||
|
||||
this.name = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Generate(MibCFile generatedFile, MibHeaderFile generatedHeaderFile)
|
||||
{
|
||||
int declCount = generatedFile.Declarations.Count;
|
||||
int implCount = generatedFile.Implementation.Count;
|
||||
|
||||
this.GenerateHeaderCode(generatedHeaderFile);
|
||||
this.GenerateCode(generatedFile);
|
||||
|
||||
if (generatedFile.Declarations.Count != declCount)
|
||||
{
|
||||
generatedFile.Declarations.Add(EmptyLine.SingleLine);
|
||||
}
|
||||
if (generatedFile.Implementation.Count != implCount)
|
||||
{
|
||||
generatedFile.Implementation.Add(EmptyLine.SingleLine);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void GenerateCode(MibCFile mibFile);
|
||||
|
||||
public virtual void GenerateHeaderCode(MibHeaderFile mibHeaderFile)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called after node structure creation is completed and before code is created.
|
||||
/// Offers the possibility to perform operations depending on properties/subnodes.
|
||||
/// If the node shall be transformed to another node(-type) than the own instance
|
||||
/// may be replaced on parent node by the transformed instance.
|
||||
/// Calling sequence is always from leafs up to root. So a tree node can assume
|
||||
/// that the analyze method was already called on all child nodes.
|
||||
/// E.g. a tree node only has scalar sub nodes -> it transforms itself to a scalar array node
|
||||
/// </summary>
|
||||
/// <returns>The transformed node or null if nothing shall be changed in parent structure.</returns>
|
||||
public virtual void Analyze()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user