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:
Michael Sauer
2026-09-11 12:52:26 +02:00
parent 4e7ff78fc6
commit 1b0501179d
610 changed files with 224089 additions and 0 deletions
+43
View File
@@ -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)
+237
View File
@@ -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
+35
View File
@@ -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
+157
View File
@@ -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(&current_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, &current_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, &current_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, &current_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(&current_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;
}
+23
View File
@@ -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
+42
View File
@@ -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
+163
View File
@@ -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__ */
+42
View File
@@ -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)
+390
View File
@@ -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
+128
View File
@@ -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__ */
+46
View File
@@ -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
+318
View File
@@ -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
+673
View File
@@ -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
+93
View File
@@ -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
+42
View File
@@ -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_
+433
View File
@@ -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
+23
View File
@@ -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
+754
View File
@@ -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
+121
View File
@@ -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
+8
View File
@@ -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
+307
View File
@@ -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);
}
+235
View File
@@ -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
+91
View File
@@ -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
+93
View File
@@ -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 */
+122
View File
@@ -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 */
+54
View File
@@ -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
+15
View File
@@ -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.
+181
View File
@@ -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
+115
View File
@@ -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 */
+246
View File
@@ -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 */
+413
View File
@@ -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 */
+221
View File
@@ -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 */
+370
View File
@@ -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
+552
View File
@@ -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 */
+179
View File
@@ -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>
&nbsp;
</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>
&nbsp;
</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 */
+97
View File
@@ -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 */
@@ -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();
}
}
}
@@ -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();
}
}
}
@@ -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);
}
}
}
@@ -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();
}
}
}
}
@@ -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();
}
}
}
}
@@ -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
@@ -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
}
}
@@ -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>
@@ -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>
@@ -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());
}
}
}
@@ -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")]
@@ -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;
}
}
}
}
@@ -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>
@@ -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;
}
}
}
}
@@ -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>
@@ -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);
}
}
}
@@ -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
}
}
@@ -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>
@@ -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
}
}
@@ -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
}
}
@@ -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));
}
}
}
@@ -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