40 Commits

Author SHA1 Message Date
069a81350e Merge branch 'hotfix/v3.1.3' 2017-09-04 12:32:08 +09:00
6411bf0ab7 Fix #13 issue. 2017-09-04 12:31:22 +09:00
9c5cc07ce5 Fix #12 issue. 2017-09-04 12:31:12 +09:00
bfa6ff10d4 Merge branch 'hotfix/v3.1.2' 2017-08-28 09:22:41 +09:00
69a005ad56 Fixed compile errors after adding IPRAW and MQTT. 2017-08-28 09:22:02 +09:00
0ea55bc8ff Bug fix : fixed IPraw & MACraw Sendto function 2016-12-14 16:50:20 +09:00
9324515f69 add to history about MQTT Client 2016-12-05 16:10:54 +09:00
6de54d2bc7 add to paho MQTT 3.1.1 (ioLibrary interface porting) 2016-12-05 16:07:02 +09:00
0a3ce81329 Revert "Add W5100S.c W5100S.h"
This reverts commit 7c1f381d54.
2016-10-26 11:15:43 +09:00
7c1f381d54 Add W5100S.c W5100S.h 2016-10-26 10:46:14 +09:00
d1ebb59d7f V3.0.3
* In W5300, Fixed some compile errors in close(). Refer to M20160503
* In close(), replace socket() with some command sequences.
2016-05-04 17:04:34 +09:00
5cc730f59d function listen() bug fixed
in !SOCK_LISTEN status... Sn_CR register check need not
2016-04-28 08:55:06 +09:00
a1302a3cb2 Socket_API_V3.0.3.chm renamed 3.0.3
Just rennamed.
2016-04-26 13:16:10 +09:00
90c6bb4ee8 V3.0.2
Applied the erratum 1 of W5300.
Refer to A20160426.
2016-04-26 13:13:03 +09:00
4a56e66867 Update README.md 2015-11-23 09:28:15 +09:00
0c5226e19b Update README.md 2015-11-23 09:26:44 +09:00
376247f51b Merge pull request #10 from Wiznet/Ricky-Kwon-patch-1
Update w5300.h
2015-09-24 14:24:05 +09:00
adf6d9c3ee Update w5300.h
fix some bug
2015-09-15 15:03:13 +09:00
241045068d Merge branch 'hotfix/v2.0.3' 2015-08-28 13:55:55 +09:00
0cabf536fd Fixed an issue #9. 2015-08-28 13:54:59 +09:00
d9e2bd1d65 Merge pull request #8 from fetzerch/wizchip_conf
wizchip_conf: Enable configuration without modifying file
2015-08-13 14:45:36 +09:00
fb3fdf47cc wizchip_conf: Enable configuration without modifying file
This encloses all user configuration options with preprocessor
ifndef ... endif guards, so that the configuration can be applied
already from the Makefile (for example with gcc -D_WIZCHIP_=5100 or
when using CMake: add_definitions(-D_WIZCHIP_=5100)).

The advantage of this change is that the ioLibrary can then simply be
included as a git submodule from the official upstream repository into
the own project without having to carry along a patch of
wizchip_conf.h.
2015-07-24 10:24:47 +02:00
942164d421 V3.0.1
Bug fixed : In W5100, CS control problem to read/write buffer with SPI.
2015-07-15 16:22:02 +09:00
1e940bbf14 Version V3.0
Add to W5300
2015-06-04 20:41:00 +09:00
bd4a3a8d55 Merge branch 'hotfix/v2.0.2' 2015-04-24 13:54:12 +09:00
989f08ab2d Removed unnessary code. 2015-04-24 13:52:22 +09:00
cd0b8f5ba9 getSIMR() & getSIMR() in w5200.h
In w5200.h,
Remove  the Mask value 0xA0 in getSIMR() & setSIMR()
Add to the Mask value 0xA0 in getIR() & setIR()
2015-04-17 13:33:42 +09:00
8508482bc4 Merge branch 'hotfix/opimization_FTP_client' 2015-04-15 17:29:54 +09:00
c2b6716e43 optimization FTP client 2015-04-15 17:29:42 +09:00
580241080d Merge branch 'hotfix/fix_compile_error' 2015-04-15 16:40:19 +09:00
c29dc21040 fix compile error 2015-04-15 16:39:46 +09:00
b840aa13a2 Merge pull request #6 from Wiznet/feature/FTP_Client_optimization
FTP Client optimization
2015-04-14 16:55:41 +09:00
b6b808b306 FTP Client optimization 2015-04-14 15:26:20 +09:00
924ceea741 Merge pull request #5 from Wiznet/develop
FTP Client optimization
2015-04-14 11:21:19 +09:00
86726229f0 FTP Client optimization 2015-04-14 11:05:02 +09:00
2857b805d9 Sync the code & doxygen document! 2015-04-13 09:42:44 +09:00
065b096c92 Modify setIMR() & getIMR() and setSIMR() & getSIMR()
In order to integrate W5200 with ioLibrary
setIMR() & getIMR(): Set/Get a value to IMR2 intead of _IMR_.
setIMR2() & getIMR2() (setSIMR() & getSIMR()) : Set/Get a value to _IMR_
instead of IMR2
2015-04-13 09:28:29 +09:00
f36dd4352a Fixed the Type casting Error in send() ,socket.c 2015-04-09 14:56:48 +09:00
19ae79ee07 Added W5100, W5200 drivers. 2015-04-06 13:27:41 +09:00
fc3430b71a Add to W5200 & W5100
Integrate ioLibrary with WIZnet chips as W5500,W5200, W5100 and so on.
2015-04-06 10:58:45 +09:00
40 changed files with 11696 additions and 436 deletions

Binary file not shown.

386
Ethernet/W5100/w5100.c Normal file
View File

@ -0,0 +1,386 @@
//*****************************************************************************
//
//! \file w5100.c
//! \brief W5100 HAL Interface.
//! \version 1.0.0
//! \date 2013/10/21
//! \par Revision history
//! <2013/10/21> 1st Release
//! \author MidnightCow
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * 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.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include "w5100.h"
#if (_WIZCHIP_ == 5100)
/**
@brief This function writes the data into W5200 registers.
*/
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
{
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
WIZCHIP.IF.SPI._write_byte(0xF0);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data)
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
//M20150601 : Rename the function for integrating with ioLibrary
//WIZCHIP.IF.BUS._write_byte(AddrSel,wb);
WIZCHIP.IF.BUS._write_data(AddrSel,wb);
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
//add indirect bus
//M20150601 : Rename the function for integrating with ioLibrary
//WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
//WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
//WIZCHIP.IF.BUS._write_byte(IDM_DR,wb);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
WIZCHIP.IF.BUS._write_data(IDM_DR,wb);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
/**
@brief This function reads the value from W5200 registers.
*/
uint8_t WIZCHIP_READ(uint32_t AddrSel)
{
uint8_t ret;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
WIZCHIP.IF.SPI._write_byte(0x0F);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >> 0);
ret = WIZCHIP.IF.SPI._read_byte();
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
//M20150601 : Rename the function for integrating with ioLibrary
//ret = WIZCHIP.IF.BUS._read_byte(AddrSel);
ret = WIZCHIP.IF.BUS._read_data(AddrSel);
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
//add indirect bus
//M20150601 : Rename the function for integrating with ioLibrary
//WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
//WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
//ret = WIZCHIP.IF.BUS._read_byte(IDM_DR);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
return ret;
}
/**
@brief This function writes into W5200 memory(Buffer)
*/
void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint16_t i = 0;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select(); //M20150601 : Moved here.
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
for(i = 0; i < len; i++)
{
//M20160715 : Depricated "M20150601 : Remove _select() to top-side"
// CS should be controlled every SPI frames
WIZCHIP.CS._select();
WIZCHIP.IF.SPI._write_byte(0xF0);
WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >> 8);
WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >> 0);
WIZCHIP.IF.SPI._write_byte(pBuf[i]); // Data write (write 1byte data)
//M20160715 : Depricated "M20150601 : Remove _select() to top-side"
WIZCHIP.CS._deselect();
}
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
for(i = 0; i < len; i++)
//M20150601 : Rename the function for integrating with ioLibrary
// WIZCHIP.IF.BUS._write_byte(AddrSel+i,pBuf[i]);
WIZCHIP.IF.BUS._write_data(AddrSel+i,pBuf[i]);
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
//M20150601 : Rename the function for integrating with ioLibrary
/*
WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI);
WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
for(i = 0 ; i < len; i++)
WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]);
WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
*/
setMR(getMR()|MR_AI);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
for(i = 0 ; i < len; i++)
WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]);
setMR(getMR() & ~MR_AI);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!!"
#endif
WIZCHIP.CS._deselect(); //M20150601 : Moved here.
WIZCHIP_CRITICAL_EXIT();
}
/**
@brief This function reads into W5200 memory(Buffer)
*/
void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint16_t i = 0;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select(); //M20150601 : Moved here.
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
for(i = 0; i < len; i++)
{
//M20160715 : Depricated "M20150601 : Remove _select() to top-side"
// CS should be controlled every SPI frames
WIZCHIP.CS._select();
WIZCHIP.IF.SPI._write_byte(0x0F);
WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >> 8);
WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >> 0);
pBuf[i] = WIZCHIP.IF.SPI._read_byte();
//M20160715 : Depricated "M20150601 : Remove _select() to top-side"
WIZCHIP.CS._deselect();
}
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
for(i = 0 ; i < len; i++)
//M20150601 : Rename the function for integrating with ioLibrary
// pBuf[i] = WIZCHIP.IF.BUS._read_byte(AddrSel+i);
pBuf[i] = WIZCHIP.IF.BUS._read_data(AddrSel+i);
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
//M20150601 : Rename the function for integrating with ioLibrary
/*
WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI);
WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
for(i = 0 ; i < len; i++)
pBuf[i] = WIZCHIP.IF.BUS._read_byte(IDM_DR);
WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
*/
setMR(getMR() | MR_AI);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
for(i = 0 ; i < len; i++)
pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR);
setMR(getMR() & ~MR_AI);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!!"
#endif
WIZCHIP.CS._deselect(); //M20150601 : Moved Here.
WIZCHIP_CRITICAL_EXIT();
}
///////////////////////////////////
// Socket N regsiter IO function //
///////////////////////////////////
uint16_t getSn_TX_FSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_TX_FSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
}
}while (val != val1);
return val;
}
uint16_t getSn_RX_RSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_RX_RSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
}
}while (val != val1);
return val;
}
/////////////////////////////////////
// Sn_TXBUF & Sn_RXBUF IO function //
/////////////////////////////////////
uint32_t getSn_RxBASE(uint8_t sn)
{
int8_t i;
#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
uint32_t rxbase = _W5100_IO_BASE_ + _WIZCHIP_IO_RXBUF_;
#else
uint32_t rxbase = _WIZCHIP_IO_RXBUF_;
#endif
for(i = 0; i < sn; i++)
rxbase += getSn_RxMAX(i);
return rxbase;
}
uint32_t getSn_TxBASE(uint8_t sn)
{
int8_t i;
#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
uint32_t txbase = _W5100_IO_BASE_ + _WIZCHIP_IO_TXBUF_;
#else
uint32_t txbase = _WIZCHIP_IO_TXBUF_;
#endif
for(i = 0; i < sn; i++)
txbase += getSn_TxMAX(i);
return txbase;
}
/**
@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip.
This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
register. User should read upper byte first and lower byte later to get proper value.
And this function is being used for copy the data form application buffer to Transmite
buffer of the chip. It calculate the actual physical address where one has to write
the data in transmite buffer. Here also take care of the condition while it exceed
the Tx memory uper-bound of socket.
*/
void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr;
uint16_t size;
uint16_t dst_mask;
uint16_t dst_ptr;
ptr = getSn_TX_WR(sn);
dst_mask = ptr & getSn_TxMASK(sn);
dst_ptr = getSn_TxBASE(sn) + dst_mask;
if (dst_mask + len > getSn_TxMAX(sn))
{
size = getSn_TxMAX(sn) - dst_mask;
WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
wizdata += size;
size = len - size;
dst_ptr = getSn_TxBASE(sn);
WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
}
else
{
WIZCHIP_WRITE_BUF(dst_ptr, wizdata, len);
}
ptr += len;
setSn_TX_WR(sn, ptr);
}
/**
@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer.
This function read the Rx read pointer register
and after copy the data from receive buffer update the Rx write pointer register.
User should read upper byte first and lower byte later to get proper value.
It calculate the actual physical address where one has to read
the data from Receive buffer. Here also take care of the condition while it exceed
the Rx memory uper-bound of socket.
*/
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr;
uint16_t size;
uint16_t src_mask;
uint16_t src_ptr;
ptr = getSn_RX_RD(sn);
src_mask = (uint32_t)ptr & getSn_RxMASK(sn);
src_ptr = (getSn_RxBASE(sn) + src_mask);
if( (src_mask + len) > getSn_RxMAX(sn) )
{
size = getSn_RxMAX(sn) - src_mask;
WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
wizdata += size;
size = len - size;
src_ptr = getSn_RxBASE(sn);
WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, size);
}
else
{
WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, len);
}
ptr += len;
setSn_RX_RD(sn, ptr);
}
void wiz_recv_ignore(uint8_t sn, uint16_t len)
{
uint16_t ptr;
ptr = getSn_RX_RD(sn);
ptr += len;
setSn_RX_RD(sn,ptr);
}
#endif

1856
Ethernet/W5100/w5100.h Normal file

File diff suppressed because it is too large Load Diff

353
Ethernet/W5200/w5200.c Normal file
View File

@ -0,0 +1,353 @@
//*****************************************************************************
//
//! \file w5200.c
//! \brief W5200 HAL Interface.
//! \version 1.0.0
//! \date 2013/10/21
//! \par Revision history
//! <2013/10/21> 1st Release
//! \author MidnightCow
//!
//! Copyright (c) 2013, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * 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.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include "w5200.h"
#if (_WIZCHIP_ == 5200)
/**
@brief This function writes the data into W5200 registers.
*/
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
{
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
WIZCHIP.IF.SPI._write_byte(_W5200_SPI_WRITE_); // Data write command and Write data length upper
WIZCHIP.IF.SPI._write_byte(0x01); // Write data length lower
WIZCHIP.IF.SPI._write_byte(wb); // Data write (write 1byte data)
#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
//add indirect bus
//M20150601 : Rename the function for integrating with W5300
//WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
//WIZCHIP.IF.BUS._write_byte(IDM_DR,wb);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
WIZCHIP.IF.BUS._write_data(IDM_DR,wb);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
/**
@brief This function reads the value from W5200 registers.
*/
uint8_t WIZCHIP_READ(uint32_t AddrSel)
{
uint8_t ret;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
WIZCHIP.IF.SPI._write_byte(_W5200_SPI_READ_); // Read data length upper
WIZCHIP.IF.SPI._write_byte(0x01); // Data length lower
ret = WIZCHIP.IF.SPI._read_byte();
#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
//add indirect bus
//M20150601 : Rename the function for integrating with W5300
//WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
//WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
//ret = WIZCHIP.IF.BUS._read_byte(IDM_DR);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
return ret;
}
/**
@brief This function writes into W5200 memory(Buffer)
*/
void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint16_t i = 0;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
WIZCHIP.IF.SPI._write_byte(_W5200_SPI_WRITE_ | ((len & 0x7F00) >> 8)); // Write data op code and length upper
WIZCHIP.IF.SPI._write_byte((len & 0x00FF) >> 0); // length lower
for(i = 0; i < len; i++)
WIZCHIP.IF.SPI._write_byte(pBuf[i]);
#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
//M20150601 : Rename the function for integrating with W5300
/*
WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI);
WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
for(i = 0 ; i < len; i++)
WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]);
WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
*/
setMR(getMR() | MR_AI);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
for(i = 0 ; i < len; i++)
WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]);
WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
/**
@brief This function reads into W5200 memory(Buffer)
*/
void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint16_t i = 0;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
WIZCHIP.IF.SPI._write_byte( _W5200_SPI_READ_ | ((len & 0x7F00) >> 8)); // Write data op code and length upper
WIZCHIP.IF.SPI._write_byte((len & 0x00FF) >> 0); // length lower
for(i = 0; i < len; i++)
pBuf[i] = WIZCHIP.IF.SPI._read_byte();
#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
//M20150601 : Rename the function for integrating with W5300
/*
WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI);
WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x000000FF));
for(i = 0 ; i < len; i++)
pBuf[i] = WIZCHIP.IF.BUS._read_byte(IDM_DR);
WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);
*/
setMR(getMR() | MR_AI);
WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x000000FF));
for(i = 0 ; i < len; i++)
pBuf[i] = WIZCHIP.IF.BUS._read_data(IDM_DR);
setMR(getMR() & ~MR_AI);
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5200. !!!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
///////////////////////////////////
// Socket N regsiter IO function //
///////////////////////////////////
uint16_t getSn_TX_FSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_TX_FSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
}
}while (val != val1);
return val;
}
uint16_t getSn_RX_RSR(uint8_t sn)
{
uint16_t val=0,val1=0;
do
{
val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
if (val1 != 0)
{
val = WIZCHIP_READ(Sn_RX_RSR(sn));
val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
}
}while (val != val1);
return val;
}
/////////////////////////////////////
// Sn_TXBUF & Sn_RXBUF IO function //
/////////////////////////////////////
uint16_t getSn_RxBASE(uint8_t sn)
{
int8_t i;
uint16_t rxbase = _WIZCHIP_IO_RXBUF_;
for(i = 0; i < sn; i++)
rxbase += getSn_RxMAX(i);
return rxbase;
}
uint16_t getSn_TxBASE(uint8_t sn)
{
int8_t i;
uint16_t txbase = _WIZCHIP_IO_TXBUF_;
for(i = 0; i < sn; i++)
txbase += getSn_TxMAX(i);
return txbase;
}
/**
@brief This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip.
This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
register. User should read upper byte first and lower byte later to get proper value.
And this function is being used for copy the data form application buffer to Transmite
buffer of the chip. It calculate the actual physical address where one has to write
the data in transmite buffer. Here also take care of the condition while it exceed
the Tx memory uper-bound of socket.
*/
void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr;
uint16_t size;
uint16_t dst_mask;
uint8_t * dst_ptr;
ptr = getSn_TX_WR(sn);
dst_mask = (uint32_t)ptr & getSn_TxMASK(sn);
dst_ptr = (uint8_t*)((uint32_t)getSn_TxBASE(sn) + dst_mask);
if (dst_mask + len > getSn_TxMAX(sn))
{
size = getSn_TxMAX(sn) - dst_mask;
WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, size);
wizdata += size;
size = len - size;
dst_ptr = (uint8_t*)((uint32_t)getSn_TxBASE(sn));
WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, size);
}
else
{
WIZCHIP_WRITE_BUF((uint32_t)dst_ptr, wizdata, len);
}
ptr += len;
setSn_TX_WR(sn, ptr);
}
/**
@brief This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer.
This function read the Rx read pointer register
and after copy the data from receive buffer update the Rx write pointer register.
User should read upper byte first and lower byte later to get proper value.
It calculate the actual physical address where one has to read
the data from Receive buffer. Here also take care of the condition while it exceed
the Rx memory uper-bound of socket.
*/
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
{
uint16_t ptr;
uint16_t size;
uint16_t src_mask;
uint8_t * src_ptr;
ptr = getSn_RX_RD(sn);
src_mask = (uint32_t)ptr & getSn_RxMASK(sn);
src_ptr = (uint8_t *)((uint32_t)getSn_RxBASE(sn) + src_mask);
if( (src_mask + len) > getSn_RxMAX(sn) )
{
size = getSn_RxMAX(sn) - src_mask;
WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
wizdata += size;
size = len - size;
src_ptr = (uint8_t*)((uint32_t)getSn_RxBASE(sn));
WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
}
else
{
WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, len);
}
ptr += len;
setSn_RX_RD(sn, ptr);
}
void wiz_recv_ignore(uint8_t sn, uint16_t len)
{
uint16_t ptr;
ptr = getSn_RX_RD(sn);
ptr += len;
setSn_RX_RD(sn,ptr);
}
#endif

2101
Ethernet/W5200/w5200.h Normal file

File diff suppressed because it is too large Load Diff

225
Ethernet/W5300/w5300.c Normal file
View File

@ -0,0 +1,225 @@
//*****************************************************************************
//
//! \file w5300.h
//! \brief W5300 HAL implement File.
//! \version 1.0.0
//! \date 2015/05/01
//! \par Revision history
//! <2015/05/01> 1st Released for integrating with ioLibrary
//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
//! >> https://github.com/Wiznet/ioLibrary_Driver
//! \author MidnightCow
//! \copyright
//!
//! Copyright (c) 2015, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * 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.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include <stdint.h>
#include "wizchip_conf.h"
#if _WIZCHIP_ == 5300
extern uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_];
extern uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_];
/***********************
* Basic I/O Function *
***********************/
void WIZCHIP_WRITE(uint32_t AddrSel, uint16_t wb )
{
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
#if(_WIZCHIP_IO_BUS_WIDTH_ == 8)
WIZCHIP.IF.BUS._write_data(AddrSel, (uint8_t)(wb>>8));
WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(AddrSel,1),(uint8_t)wb);
#elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
WIZCHIP.IF.BUS._write_data(AddrSel, wb);
#else
#error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
#endif
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
#if(_WIZCHIP_IO_BUS_WIDTH_ == 8)
WIZCHIP.IF.BUS._write_data(IDM_AR, (uint8_t)(AddrSel >> 8));
WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_AR,1),(uint8_t)AddrSel);
WIZCHIP.IF.BUS._write_data(IDM_DR,(uint8_t)(wb>>8));
WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_DR,1),(uint8_t)wb);
#elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
WIZCHIP.IF.BUS._write_data(IDM_AR, (uint16_t)AddrSel);
WIZCHIP.IF.BUS._write_data(IDM_DR, wb);
#else
#error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
#endif
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5300. !!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
uint16_t WIZCHIP_READ(uint32_t AddrSel)
{
uint16_t ret;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) )
#if (_WIZCHIP_IO_BUS_WIDTH_ == 8)
ret = (((uint16_t)WIZCHIP.IF.BUS._read_data(AddrSel)) << 8) |
(((uint16_t)WIZCHIP.IF.BUS._read_data(WIZCHIP_OFFSET_INC(AddrSel,1))) & 0x00FF) ;
#elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
ret = WIZCHIP.IF.BUS._read_data(AddrSel);
#else
#error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
#endif
#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
#if(_WIZCHIP_IO_BUS_WIDTH_ == 8)
WIZCHIP.IF.BUS._write_data(IDM_AR, (uint8_t)(AddrSel >> 8));
WIZCHIP.IF.BUS._write_data(WIZCHIP_OFFSET_INC(IDM_AR,1),(uint8_t)AddrSel);
ret = (((uint16_t)WIZCHIP.IF.BUS._read_data(IDM_DR)) << 8) |
(((uint16_t)WIZCHIP.IF.BUS._read_data(WIZCHIP_OFFSET_INC(IDM_DR,1))) & 0x00FF);
#elif(_WIZCHIP_IO_BUS_WIDTH_ == 16)
WIZCHIP.IF.BUS._write_data(IDM_AR, (uint16_t)AddrSel);
ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
#else
#error "Abnoraml _WIZCHIP_IO_BUS_WIDTH_. Should be 8 or 16"
#endif
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5300. !!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
return ret;
}
void setTMSR(uint8_t sn,uint8_t tmsr)
{
uint16_t tmem;
tmem = WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE)));
if(sn & 0x01) tmem = (tmem & 0xFF00) | (((uint16_t)tmsr ) & 0x00FF) ;
else tmem = (tmem & 0x00FF) | (((uint16_t)tmsr) << 8) ;
WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE)),tmem);
}
uint8_t getTMSR(uint8_t sn)
{
if(sn & 0x01)
return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE))) & 0x00FF);
return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(TMS01R, (sn & 0xFE))) >> 8);
}
void setRMSR(uint8_t sn,uint8_t rmsr)
{
uint16_t rmem;
rmem = WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE)));
if(sn & 0x01) rmem = (rmem & 0xFF00) | (((uint16_t)rmsr ) & 0x00FF) ;
else rmem = (rmem & 0x00FF) | (((uint16_t)rmsr) << 8) ;
WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE)),rmem);
}
uint8_t getRMSR(uint8_t sn)
{
if(sn & 0x01)
return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE))) & 0x00FF);
return (uint8_t)(WIZCHIP_READ(WIZCHIP_OFFSET_INC(RMS01R, (sn & 0xFE))) >> 8);
}
uint32_t getSn_TX_FSR(uint8_t sn)
{
uint32_t free_tx_size=0;
uint32_t free_tx_size1=1;
while(1)
{
free_tx_size = (((uint32_t)WIZCHIP_READ(Sn_TX_FSR(sn))) << 16) |
(((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),2))) & 0x0000FFFF); // read
if(free_tx_size == free_tx_size1) break; // if first == sencond, Sn_TX_FSR value is valid.
free_tx_size1 = free_tx_size; // save second value into first
}
return free_tx_size;
}
uint32_t getSn_RX_RSR(uint8_t sn)
{
uint32_t received_rx_size=0;
uint32_t received_rx_size1=1;
while(1)
{
received_rx_size = (((uint32_t)WIZCHIP_READ(Sn_RX_RSR(sn))) << 16) |
(((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),2))) & 0x0000FFFF);
if(received_rx_size == received_rx_size1) break;
received_rx_size1 = received_rx_size; // if first == sencond, Sn_RX_RSR value is valid.
} // save second value into first
return received_rx_size + (uint32_t)((sock_pack_info[sn] & 0x02) ? 1 : 0);
}
void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint32_t len)
{
uint32_t i = 0;
if(len == 0) return;
for(i = 0; i < len ; i += 2)
setSn_TX_FIFOR(sn, (((uint16_t)wizdata[i]) << 8) | (((uint16_t)wizdata[i+1]) & 0x00FF))
}
void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint32_t len)
{
uint16_t rd = 0;
uint32_t i = 0;
if(len == 0) return;
for(i = 0; i < len; i++)
{
if((i & 0x01)==0)
{
rd = getSn_RX_FIFOR(sn);
wizdata[i] = (uint8_t)(rd >> 8);
}
else wizdata[i] = (uint8_t)rd; // For checking the memory access violation
}
sock_remained_byte[sn] = (uint8_t)rd; // back up the remaind fifo byte.
}
void wiz_recv_ignore(uint8_t sn, uint32_t len)
{
uint32_t i = 0;
for(i = 0; i < len ; i += 2) getSn_RX_FIFOR(sn);
}
#endif

2327
Ethernet/W5300/w5300.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -59,6 +59,7 @@
#define _W5500_SPI_FDM_OP_LEN2_ 0x02 #define _W5500_SPI_FDM_OP_LEN2_ 0x02
#define _W5500_SPI_FDM_OP_LEN4_ 0x03 #define _W5500_SPI_FDM_OP_LEN4_ 0x03
#if (_WIZCHIP_ == 5500)
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
uint8_t WIZCHIP_READ(uint32_t AddrSel) uint8_t WIZCHIP_READ(uint32_t AddrSel)
@ -263,3 +264,4 @@ void wiz_recv_ignore(uint8_t sn, uint16_t len)
setSn_RX_RD(sn,ptr); setSn_RX_RD(sn,ptr);
} }
#endif

View File

@ -43,12 +43,18 @@
// //
//***************************************************************************** //*****************************************************************************
//
#ifndef _W5500_H_ #ifndef _W5500_H_
#define _W5500_H_ #define _W5500_H_
#include <stdint.h> #include <stdint.h>
#include "wizchip_conf.h" #include "wizchip_conf.h"
/// @cond DOXY_APPLY_CODE
#if (_WIZCHIP_ == 5500)
/// @endcond
#define _W5500_IO_BASE_ 0x00000000 #define _W5500_IO_BASE_ 0x00000000
#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase #define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase
@ -147,7 +153,7 @@
* @sa MR : Mode register. * @sa MR : Mode register.
* @sa GAR, SUBR, SHAR, SIPR * @sa GAR, SUBR, SHAR, SIPR
* @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt.
* @sa RTR, RCR : Data retransmission. * @sa _RTR_, _RCR_ : Data retransmission.
* @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE.
* @sa UIPR, UPORTR : ICMP message. * @sa UIPR, UPORTR : ICMP message.
* @sa PHYCFGR, VERSIONR : etc. * @sa PHYCFGR, VERSIONR : etc.
@ -262,10 +268,10 @@
/** /**
* @ingroup Common_register_group * @ingroup Common_register_group
* @brief Interrupt mask register(R/W) * @brief Interrupt mask register(R/W)
* @details @ref IMR is used to mask interrupts. Each bit of @ref IMR corresponds to each bit of @ref IR. * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ corresponds to each bit of @ref IR.
* When a bit of @ref IMR is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, * When a bit of @ref _IMR_ is and the corresponding bit of @ref IR is an interrupt will be issued. In other words,
* if a bit of @ref IMR is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n * if a bit of @ref _IMR_ is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n
* Each bit of @ref IMR defined as the following. * Each bit of @ref _IMR_ defined as the following.
* <table> * <table>
* <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr>
* <tr> <td>IM_IR7</td> <td>IM_IR6</td> <td>IM_IR5</td> <td>IM_IR4</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr> * <tr> <td>IM_IR7</td> <td>IM_IR6</td> <td>IM_IR5</td> <td>IM_IR4</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr>
@ -275,7 +281,9 @@
* - \ref IM_IR5 : PPPoE Close Interrupt Mask * - \ref IM_IR5 : PPPoE Close Interrupt Mask
* - \ref IM_IR4 : Magic Packet Interrupt Mask * - \ref IM_IR4 : Magic Packet Interrupt Mask
*/ */
#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) //M20150401 : Rename SYMBOE ( Re-define error in a compile)
//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3))
#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3))
/** /**
* @ingroup Common_register_group * @ingroup Common_register_group
@ -297,20 +305,24 @@
/** /**
* @ingroup Common_register_group * @ingroup Common_register_group
* @brief Timeout register address( 1 is 100us )(R/W) * @brief Timeout register address( 1 is 100us )(R/W)
* @details @ref RTR configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref RTR is x07D0or 000 * @details @ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref _RTR_ is x07D0.
* And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref RTR, W5500 waits for the peer response * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref _RTR_, W5500 waits for the peer response
* to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
* If the peer does not respond within the @ref RTR time, W5500 retransmits the packet or issues timeout. * If the peer does not respond within the @ref _RTR_ time, W5500 retransmits the packet or issues timeout.
*/ */
#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) //M20150401 : Rename SYMBOE ( Re-define error in a compile)
//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3))
#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3))
/** /**
* @ingroup Common_register_group * @ingroup Common_register_group
* @brief Retry count register(R/W) * @brief Retry count register(R/W)
* @details @ref RCR configures the number of time of retransmission. * @details @ref _RCR_ configures the number of time of retransmission.
* When retransmission occurs as many as ref RCR+1 Timeout interrupt is issued (@ref Sn_IR[TIMEOUT] = . * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (@ref Sn_IR_TIMEOUT = '1').
*/ */
#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) //M20150401 : Rename SYMBOE ( Re-define error in a compile)
//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3))
#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3))
/** /**
* @ingroup Common_register_group * @ingroup Common_register_group
@ -351,7 +363,7 @@
* @ingroup Common_register_group * @ingroup Common_register_group
* @brief Unreachable IP register address in UDP mode(R) * @brief Unreachable IP register address in UDP mode(R)
* @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number
* which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates
* the destination IP address & port number respectively. * the destination IP address & port number respectively.
*/ */
#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) #define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3))
@ -360,7 +372,7 @@
* @ingroup Common_register_group * @ingroup Common_register_group
* @brief Unreachable Port register address in UDP mode(R) * @brief Unreachable Port register address in UDP mode(R)
* @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number
* which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR
* indicates the destination IP address & port number respectively. * indicates the destination IP address & port number respectively.
*/ */
#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) #define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3))
@ -488,7 +500,7 @@
* @ingroup Socket_register_group * @ingroup Socket_register_group
* @brief source port register(R/W) * @brief source port register(R/W)
* @details @ref Sn_PORT configures the source port number of Socket n. * @details @ref Sn_PORT configures the source port number of Socket n.
* It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
*/ */
#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) #define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
@ -504,8 +516,8 @@
* @ingroup Socket_register_group * @ingroup Socket_register_group
* @brief Peer IP register address(R/W) * @brief Peer IP register address(R/W)
* @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
* In TCP client mode, it configures an IP address of <EFBFBD>TCP serverbefore CONNECT command. * In TCP client mode, it configures an IP address of TCP serverbefore CONNECT command.
* In TCP server mode, it indicates an IP address of <EFBFBD>TCP clientafter successfully establishing connection. * In TCP server mode, it indicates an IP address of TCP clientafter successfully establishing connection.
* In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
*/ */
#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) #define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
@ -514,8 +526,8 @@
* @ingroup Socket_register_group * @ingroup Socket_register_group
* @brief Peer port register address(R/W) * @brief Peer port register address(R/W)
* @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
* In <EFBFBD>TCP clientmode, it configures the listen port number of <EFBFBD>TCP serverbefore CONNECT command. * In TCP clientmode, it configures the listen port number of TCP serverbefore CONNECT command.
* In <EFBFBD>TCP Servermode, it indicates the port number of TCP client after successfully establishing connection. * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
* In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
*/ */
#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) #define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
@ -819,7 +831,7 @@
* 1 : Enable No Delayed ACK option\n * 1 : Enable No Delayed ACK option\n
* This bit is applied only during TCP mode (P[3:0] = 001.\n * This bit is applied only during TCP mode (P[3:0] = 001.\n
* When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
* When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref RTR. * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref _RTR_.
*/ */
#define Sn_MR_ND 0x20 #define Sn_MR_ND 0x20
@ -838,7 +850,7 @@
*/ */
#define Sn_MR_MACRAW 0x04 #define Sn_MR_MACRAW 0x04
//#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ #define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
/** /**
* @brief UDP * @brief UDP
@ -916,46 +928,46 @@
* The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n
* <table> * <table>
* <tr> <td>\b Sn_MR (P[3:0])</td> <td>\b Sn_SR</td> </tr> * <tr> <td>\b Sn_MR (P[3:0])</td> <td>\b Sn_SR</td> </tr>
* <tr> <td>Sn_MR_CLOSE (000</td> <td></td> </tr> * <tr> <td>Sn_MR_CLOSE (000)</td> <td></td> </tr>
* <tr> <td>Sn_MR_TCP (001</td> <td>SOCK_INIT (0x13)</td> </tr> * <tr> <td>Sn_MR_TCP (001)</td> <td>SOCK_INIT (0x13)</td> </tr>
* <tr> <td>Sn_MR_UDP (010</td> <td>SOCK_UDP (0x22)</td> </tr> * <tr> <td>Sn_MR_UDP (010)</td> <td>SOCK_UDP (0x22)</td> </tr>
* <tr> <td>S0_MR_MACRAW (100</td> <td>SOCK_MACRAW (0x02)</td> </tr> * <tr> <td>S0_MR_MACRAW (100)</td> <td>SOCK_MACRAW (0x02)</td> </tr>
* </table> * </table>
*/ */
#define Sn_CR_OPEN 0x01 #define Sn_CR_OPEN 0x01
/** /**
* @brief Wait connection request in TCP mode(Server mode) * @brief Wait connection request in TCP mode(Server mode)
* @details This is valid only in TCP mode (Sn_MR(P3:P0) = Sn_MR_TCP). * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP).
* In this mode, Socket n operates as a <EFBFBD>TCP serverand waits for connection-request (SYN packet) from any <EFBFBD>TCP client * In this mode, Socket n operates as a TCP serverand waits for connection-request (SYN packet) from any TCP client
* The @ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN. * The @ref Sn_SR changes the state from \ref SOCK_INIT to \ref SOCKET_LISTEN.
* When a <EFBFBD>TCP clientconnection request is successfully established, * When a TCP clientconnection request is successfully established,
* the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes
* But when a <EFBFBD>TCP clientconnection request is failed, Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. * But when a TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED.
*/ */
#define Sn_CR_LISTEN 0x02 #define Sn_CR_LISTEN 0x02
/** /**
* @brief Send connection request in TCP mode(Client mode) * @brief Send connection request in TCP mode(Client mode)
* @details To connect, a connect-request (SYN packet) is sent to b>TCP server</b>configured by @ref Sn_DIPR & Sn_DPORT(destination address & port). * @details To connect, a connect-request (SYN packet) is sent to <b>TCP server</b>configured by @ref Sn_DIPR & Sn_DPORT(destination address & port).
* If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
* The connect-request fails in the following three cases.\n * The connect-request fails in the following three cases.\n
* 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n
* 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n
* 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED.
* @note This is valid only in TCP mode and operates when Socket n acts as b>TCP client</b> * @note This is valid only in TCP mode and operates when Socket n acts as <b>TCP client</b>
*/ */
#define Sn_CR_CONNECT 0x04 #define Sn_CR_CONNECT 0x04
/** /**
* @brief Send closing request in TCP mode * @brief Send closing request in TCP mode
* @details Regardless of b>TCP server</b>or b>TCP client</b> the DISCON command processes the disconnect-process (b>Active close</b>or b>Passive close</b>.\n * @details Regardless of <b>TCP server</b>or <b>TCP client</b> the DISCON command processes the disconnect-process (b>Active close</b>or <b>Passive close</b>.\n
* @par Active close * @par Active close
* it transmits disconnect-request(FIN packet) to the connected peer\n * it transmits disconnect-request(FIN packet) to the connected peer\n
* @par Passive close * @par Passive close
* When FIN packet is received from peer, a FIN packet is replied back to the peer.\n * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
* @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n
* Otherwise, TCPTO occurs (Sn_IR(3)=)= and then @ref Sn_SR is changed to @ref SOCK_CLOSED. * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to @ref SOCK_CLOSED.
* @note Valid only in TCP mode. * @note Valid only in TCP mode.
*/ */
#define Sn_CR_DISCON 0x08 #define Sn_CR_DISCON 0x08
@ -1034,24 +1046,24 @@
/* Sn_SR values */ /* Sn_SR values */
/** /**
* @brief Closed * @brief Closed
* @details This indicates that Socket n is released.\N * @details This indicates that Socket n is released.\n
* When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status.
*/ */
#define SOCK_CLOSED 0x00 #define SOCK_CLOSED 0x00
/** /**
* @brief Initiate state * @brief Initiate state
* @details This indicates Socket n is opened with TCP mode.\N * @details This indicates Socket n is opened with TCP mode.\n
* It is changed to @ref SOCK_INIT when Sn_MR(P[3:0]) = 001and OPEN command is ordered.\N * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN command is ordered.\n
* After @ref SOCK_INIT, user can use LISTEN /CONNECT command. * After @ref SOCK_INIT, user can use LISTEN /CONNECT command.
*/ */
#define SOCK_INIT 0x13 #define SOCK_INIT 0x13
/** /**
* @brief Listen state * @brief Listen state
* @details This indicates Socket n is operating as b>TCP server</b>mode and waiting for connection-request (SYN packet) from a peer (b>TCP client</b>.\n * @details This indicates Socket n is operating as <b>TCP server</b>mode and waiting for connection-request (SYN packet) from a peer <b>TCP client</b>.\n
* It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n
* Otherwise it will change to @ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = . * Otherwise it will change to @ref SOCK_CLOSED after TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred.
*/ */
#define SOCK_LISTEN 0x14 #define SOCK_LISTEN 0x14
@ -1060,7 +1072,7 @@
* @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
* It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n
* If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n
* Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = is occurred. * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred.
*/ */
#define SOCK_SYNSENT 0x15 #define SOCK_SYNSENT 0x15
@ -1068,14 +1080,14 @@
* @brief Connection state * @brief Connection state
* @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
* If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n
* If not, it changes to @ref SOCK_CLOSED after timeout occurs (@ref Sn_IR[TIMEOUT] = . * If not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') is occurred.
*/ */
#define SOCK_SYNRECV 0x16 #define SOCK_SYNRECV 0x16
/** /**
* @brief Success to connect * @brief Success to connect
* @details This indicates the status of the connection of Socket n.\n * @details This indicates the status of the connection of Socket n.\n
* It changes to @ref SOCK_ESTABLISHED when the b>TCP SERVER</b>processed the SYN packet from the b>TCP CLIENT</b>during @ref SOCK_LISTEN, or * It changes to @ref SOCK_ESTABLISHED when the <b>TCP SERVER</b>processed the SYN packet from the <b>TCP CLIENT</b>during @ref SOCK_LISTEN, or
* when the CONNECT command is successful.\n * when the CONNECT command is successful.\n
* During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
*/ */
@ -1116,19 +1128,19 @@
/** /**
* @brief Closing state * @brief Closing state
* @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
* It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (@ref Sn_IR[TIMEOUT] = . * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred.
*/ */
#define SOCK_LAST_ACK 0x1D #define SOCK_LAST_ACK 0x1D
/** /**
* @brief UDP socket * @brief UDP socket
* @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010.\n * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = '010').\n
* It changes to SOCK_UPD when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n * It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref Sn_CR_OPEN command is ordered.\n
* Unlike TCP mode, data can be transfered without the connection-process. * Unlike TCP mode, data can be transfered without the connection-process.
*/ */
#define SOCK_UDP 0x22 #define SOCK_UDP 0x22
//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ #define SOCK_IPRAW 0x32 /**< IP raw mode socket */
/** /**
* @brief MAC raw mode socket * @brief MAC raw mode socket
@ -1169,6 +1181,7 @@
#ifdef _exit #ifdef _exit
#undef _exit #undef _exit
#endif #endif
/** /**
* @brief Exit a critical section * @brief Exit a critical section
* *
@ -1180,11 +1193,9 @@
* @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
* @sa WIZCHIP_CRITICAL_ENTER() * @sa WIZCHIP_CRITICAL_ENTER()
*/ */
#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() #define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit()
//////////////////////// ////////////////////////
// Basic I/O Function // // Basic I/O Function //
//////////////////////// ////////////////////////
@ -1337,8 +1348,13 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref INTLEVEL register. * @return uint16_t. Value of @ref INTLEVEL register.
* @sa setINTLEVEL() * @sa setINTLEVEL()
*/ */
//M20150401 : Type explict declaration
/*
#define getINTLEVEL() \ #define getINTLEVEL() \
((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1)))
*/
#define getINTLEVEL() \
(((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1)))
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
@ -1359,22 +1375,21 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
(WIZCHIP_READ(IR) & 0xF0) (WIZCHIP_READ(IR) & 0xF0)
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Set @ref IMR register * @brief Set @ref _IMR_ register
* @param (uint8_t)imr Value to set @ref IMR register. * @param (uint8_t)imr Value to set @ref _IMR_ register.
* @sa getIMR() * @sa getIMR()
*/ */
#define setIMR(imr) \ #define setIMR(imr) \
WIZCHIP_WRITE(IMR, imr) WIZCHIP_WRITE(_IMR_, imr)
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Get @ref IMR register * @brief Get @ref _IMR_ register
* @return uint8_t. Value of @ref IMR register. * @return uint8_t. Value of @ref _IMR_ register.
* @sa setIMR() * @sa setIMR()
*/ */
#define getIMR() \ #define getIMR() \
WIZCHIP_READ(IMR) WIZCHIP_READ(_IMR_)
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
@ -1413,41 +1428,47 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Set @ref RTR register * @brief Set @ref _RTR_ register
* @param (uint16_t)rtr Value to set @ref RTR register. * @param (uint16_t)rtr Value to set @ref _RTR_ register.
* @sa getRTR() * @sa getRTR()
*/ */
#define setRTR(rtr) {\ #define setRTR(rtr) {\
WIZCHIP_WRITE(RTR, (uint8_t)(rtr >> 8)); \ WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \
WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RTR,1), (uint8_t) rtr); \ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \
} }
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Get @ref RTR register * @brief Get @ref _RTR_ register
* @return uint16_t. Value of @ref RTR register. * @return uint16_t. Value of @ref _RTR_ register.
* @sa setRTR() * @sa setRTR()
*/ */
//M20150401 : Type explict declaration
/*
#define getRTR() \ #define getRTR() \
((WIZCHIP_READ(RTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(RTR,1))) ((WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
*/
#define getRTR() \
(((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Set @ref RCR register * @brief Set @ref _RCR_ register
* @param (uint8_t)rcr Value to set @ref RCR register. * @param (uint8_t)rcr Value to set @ref _RCR_ register.
* @sa getRCR() * @sa getRCR()
*/ */
#define setRCR(rcr) \ #define setRCR(rcr) \
WIZCHIP_WRITE(RCR, rcr) WIZCHIP_WRITE(_RCR_, rcr)
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Get @ref RCR register * @brief Get @ref _RCR_ register
* @return uint8_t. Value of @ref RCR register. * @return uint8_t. Value of @ref _RCR_ register.
* @sa setRCR() * @sa setRCR()
*/ */
#define getRCR() \ #define getRCR() \
WIZCHIP_READ(RCR) WIZCHIP_READ(_RCR_)
//================================================== test done =========================================================== //================================================== test done ===========================================================
@ -1489,7 +1510,7 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Set PHAR address * @brief Set @ref PHAR address
* @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes.
* @sa getPHAR() * @sa getPHAR()
*/ */
@ -1498,7 +1519,7 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Get local IP address * @brief Get @ref PHAR address
* @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes.
* @sa setPHAR() * @sa setPHAR()
*/ */
@ -1523,8 +1544,13 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @sa setPSID() * @sa setPSID()
*/ */
//uint16_t getPSID(void); //uint16_t getPSID(void);
//M20150401 : Type explict declaration
/*
#define getPSID() \ #define getPSID() \
((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1)))
*/
#define getPSID() \
(((uint16_t)WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1)))
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
@ -1543,24 +1569,39 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref PMRU register. * @return uint16_t. Value of @ref PMRU register.
* @sa setPMRU() * @sa setPMRU()
*/ */
//M20150401 : Type explict declaration
/*
#define getPMRU() \ #define getPMRU() \
((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1)))
*/
#define getPMRU() \
(((uint16_t)WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1)))
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Get unreachable IP address * @brief Get unreachable IP address
* @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes.
*/ */
//M20150401 : Size Error of UIPR (6 -> 4)
/*
#define getUIPR(uipr) \ #define getUIPR(uipr) \
WIZCHIP_READ_BUF(UIPR,uipr,6) WIZCHIP_READ_BUF(UIPR,uipr,6)
*/
#define getUIPR(uipr) \
WIZCHIP_READ_BUF(UIPR,uipr,4)
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
* @brief Get @ref UPORTR register * @brief Get @ref UPORTR register
* @return uint16_t. Value of @ref UPORTR register. * @return uint16_t. Value of @ref UPORTR register.
*/ */
//M20150401 : Type explict declaration
/*
#define getUPORTR() \ #define getUPORTR() \
((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1)))
*/
#define getUPORTR() \
(((uint16_t)WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1)))
/** /**
* @ingroup Common_register_access_function * @ingroup Common_register_access_function
@ -1701,8 +1742,13 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref Sn_PORT. * @return uint16_t. Value of @ref Sn_PORT.
* @sa setSn_PORT() * @sa setSn_PORT()
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_PORT(sn) \ #define getSn_PORT(sn) \
((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
*/
#define getSn_PORT(sn) \
(((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
/** /**
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
@ -1739,7 +1785,7 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @brief Get @ref Sn_DIPR register * @brief Get @ref Sn_DIPR register
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
* @sa SetSn_DIPR() * @sa setSn_DIPR()
*/ */
#define getSn_DIPR(sn, dipr) \ #define getSn_DIPR(sn, dipr) \
WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4)
@ -1763,8 +1809,13 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref Sn_DPORT. * @return uint16_t. Value of @ref Sn_DPORT.
* @sa setSn_DPORT() * @sa setSn_DPORT()
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_DPORT(sn) \ #define getSn_DPORT(sn) \
((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
*/
#define getSn_DPORT(sn) \
(((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
/** /**
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
@ -1785,8 +1836,13 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref Sn_MSSR. * @return uint16_t. Value of @ref Sn_MSSR.
* @sa setSn_MSSR() * @sa setSn_MSSR()
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_MSSR(sn) \ #define getSn_MSSR(sn) \
((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
*/
#define getSn_MSSR(sn) \
(((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
/** /**
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
@ -1885,8 +1941,13 @@ uint16_t getSn_TX_FSR(uint8_t sn);
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of @ref Sn_TX_RD. * @return uint16_t. Value of @ref Sn_TX_RD.
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_TX_RD(sn) \ #define getSn_TX_RD(sn) \
((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
*/
#define getSn_TX_RD(sn) \
(((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
/** /**
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
@ -1907,8 +1968,13 @@ uint16_t getSn_TX_FSR(uint8_t sn);
* @return uint16_t. Value of @ref Sn_TX_WR. * @return uint16_t. Value of @ref Sn_TX_WR.
* @sa setSn_TX_WR() * @sa setSn_TX_WR()
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_TX_WR(sn) \ #define getSn_TX_WR(sn) \
((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
*/
#define getSn_TX_WR(sn) \
(((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
/** /**
@ -1936,11 +2002,16 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
* @brief Get @ref Sn_RX_RD register * @brief Get @ref Sn_RX_RD register
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @regurn uint16_t. Value of @ref Sn_RX_RD. * @return uint16_t. Value of @ref Sn_RX_RD.
* @sa setSn_RX_RD() * @sa setSn_RX_RD()
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_RX_RD(sn) \ #define getSn_RX_RD(sn) \
((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
*/
#define getSn_RX_RD(sn) \
(((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
/** /**
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
@ -1948,9 +2019,13 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of @ref Sn_RX_WR. * @return uint16_t. Value of @ref Sn_RX_WR.
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_RX_WR(sn) \ #define getSn_RX_WR(sn) \
((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
*/
#define getSn_RX_WR(sn) \
(((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
/** /**
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
@ -1971,8 +2046,13 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @return uint16_t. Value of @ref Sn_FRAG. * @return uint16_t. Value of @ref Sn_FRAG.
* @sa setSn_FRAG() * @sa setSn_FRAG()
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_FRAG(sn) \ #define getSn_FRAG(sn) \
((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
*/
#define getSn_FRAG(sn) \
(((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
/** /**
* @ingroup Socket_register_access_function * @ingroup Socket_register_access_function
@ -2000,21 +2080,32 @@ uint16_t getSn_RX_RSR(uint8_t sn);
// Sn_TXBUF & Sn_RXBUF IO function // // Sn_TXBUF & Sn_RXBUF IO function //
///////////////////////////////////// /////////////////////////////////////
/** /**
* @brief Socket_register_access_function
* @brief Gets the max buffer size of socket sn passed as parameter. * @brief Gets the max buffer size of socket sn passed as parameter.
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of Socket n RX max buffer size. * @return uint16_t. Value of Socket n RX max buffer size.
*/ */
//M20150401 : Type explict declaration
/*
#define getSn_RxMAX(sn) \ #define getSn_RxMAX(sn) \
(getSn_RXBUF_SIZE(sn) << 10) (getSn_RXBUF_SIZE(sn) << 10)
*/
#define getSn_RxMAX(sn) \
(((uint16_t)getSn_RXBUF_SIZE(sn)) << 10)
/** /**
* @brief Socket_register_access_function
* @brief Gets the max buffer size of socket sn passed as parameters. * @brief Gets the max buffer size of socket sn passed as parameters.
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of Socket n TX max buffer size. * @return uint16_t. Value of Socket n TX max buffer size.
*/ */
//uint16_t getSn_TxMAX(uint8_t sn); //M20150401 : Type explict declaration
/*
#define getSn_TxMAX(sn) \ #define getSn_TxMAX(sn) \
(getSn_TXBUF_SIZE(sn) << 10) (getSn_TXBUF_SIZE(sn) << 10)
*/
#define getSn_TxMAX(sn) \
(((uint16_t)getSn_TXBUF_SIZE(sn)) << 10)
/** /**
* @ingroup Basic_IO_function * @ingroup Basic_IO_function
@ -2025,7 +2116,6 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* and updates the Tx write pointer register. * and updates the Tx write pointer register.
* This function is being called by send() and sendto() function also. * This function is being called by send() and sendto() function also.
* *
* @note User should read upper byte first and lower byte later to get proper value.
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @param wizdata Pointer buffer to write data * @param wizdata Pointer buffer to write data
* @param len Data length * @param len Data length
@ -2042,7 +2132,6 @@ void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
* to <i>wizdata(pointer variable)</i> of the length of <i>len(variable)</i> bytes. * to <i>wizdata(pointer variable)</i> of the length of <i>len(variable)</i> bytes.
* This function is being called by recv() also. * This function is being called by recv() also.
* *
* @note User should read upper byte first and lower byte later to get proper value.
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @param wizdata Pointer buffer to read data * @param wizdata Pointer buffer to read data
* @param len Data length * @param len Data length
@ -2059,4 +2148,8 @@ void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
*/ */
void wiz_recv_ignore(uint8_t sn, uint16_t len); void wiz_recv_ignore(uint8_t sn, uint16_t len);
/// @cond DOXY_APPLY_CODE
#endif
/// @endcond
#endif // _W5500_H_ #endif // _W5500_H_

View File

@ -55,18 +55,31 @@
//***************************************************************************** //*****************************************************************************
#include "socket.h" #include "socket.h"
#define SOCK_ANY_PORT_NUM 0xC000; //M20150401 : Typing Error
//#define SOCK_ANY_PORT_NUM 0xC000;
#define SOCK_ANY_PORT_NUM 0xC000
static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
static uint16_t sock_io_mode = 0; static uint16_t sock_io_mode = 0;
static uint16_t sock_is_sending = 0; static uint16_t sock_is_sending = 0;
static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
//M20150601 : For extern decleation
//static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
//
#if _WIZCHIP_ == 5200 #if _WIZCHIP_ == 5200
static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,}; static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
#endif #endif
//A20150601 : For integrating with W5300
#if _WIZCHIP_ == 5300
uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data()
#endif
#define CHECK_SOCKNUM() \ #define CHECK_SOCKNUM() \
do{ \ do{ \
if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
@ -95,6 +108,16 @@ int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
switch(protocol) switch(protocol)
{ {
case Sn_MR_TCP : case Sn_MR_TCP :
{
//M20150601 : Fixed the warning - taddr will never be NULL
/*
uint8_t taddr[4];
getSIPR(taddr);
*/
uint32_t taddr;
getSIPR((uint8_t*)&taddr);
if(taddr == 0) return SOCKERR_SOCKINIT;
}
case Sn_MR_UDP : case Sn_MR_UDP :
case Sn_MR_MACRAW : case Sn_MR_MACRAW :
break; break;
@ -106,7 +129,9 @@ int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
default : default :
return SOCKERR_SOCKMODE; return SOCKERR_SOCKMODE;
} }
if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; //M20150601 : For SF_TCP_ALIGN & W5300
//if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
if((flag & 0x04) != 0) return SOCKERR_SOCKFLAG;
#if _WIZCHIP_ == 5200 #if _WIZCHIP_ == 5200
if(flag & 0x10) return SOCKERR_SOCKFLAG; if(flag & 0x10) return SOCKERR_SOCKFLAG;
#endif #endif
@ -116,7 +141,13 @@ int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
switch(protocol) switch(protocol)
{ {
case Sn_MR_TCP: case Sn_MR_TCP:
//M20150601 : For SF_TCP_ALIGN & W5300
#if _WIZCHIP_ == 5300
if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK|SF_TCP_ALIGN))==0) return SOCKERR_SOCKFLAG;
#else
if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
#endif
break; break;
case Sn_MR_UDP: case Sn_MR_UDP:
if(flag & SF_IGMP_VER2) if(flag & SF_IGMP_VER2)
@ -135,7 +166,12 @@ int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
} }
} }
close(sn); close(sn);
//M20150601
#if _WIZCHIP_ == 5300
setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7) );
#else
setSn_MR(sn, (protocol | (flag & 0xF0))); setSn_MR(sn, (protocol | (flag & 0xF0)));
#endif
if(!port) if(!port)
{ {
port = sock_any_port++; port = sock_any_port++;
@ -144,10 +180,16 @@ int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
setSn_PORT(sn,port); setSn_PORT(sn,port);
setSn_CR(sn,Sn_CR_OPEN); setSn_CR(sn,Sn_CR_OPEN);
while(getSn_CR(sn)); while(getSn_CR(sn));
//A20150401 : For release the previous sock_io_mode
sock_io_mode &= ~(1 <<sn);
//
sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
sock_is_sending &= ~(1<<sn); sock_is_sending &= ~(1<<sn);
sock_remained_size[sn] = 0; sock_remained_size[sn] = 0;
sock_pack_info[sn] = 0; //M20150601 : repalce 0 with PACK_COMPLETED
//sock_pack_info[sn] = 0;
sock_pack_info[sn] = PACK_COMPLETED;
//
while(getSn_SR(sn) == SOCK_CLOSED); while(getSn_SR(sn) == SOCK_CLOSED);
return (int8_t)sn; return (int8_t)sn;
} }
@ -155,12 +197,39 @@ int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
int8_t close(uint8_t sn) int8_t close(uint8_t sn)
{ {
CHECK_SOCKNUM(); CHECK_SOCKNUM();
//A20160426 : Applied the erratum 1 of W5300
#if (_WIZCHIP_ == 5300)
//M20160503 : Wrong socket parameter. s -> sn
//if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) )
if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) )
{
uint8 destip[4] = {0, 0, 0, 1};
// TODO
// You can wait for completing to sending data;
// wait about 1 second;
// if you have completed to send data, skip the code of erratum 1
// ex> wait_1s();
// if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
//
//M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
//socket(s,Sn_MR_UDP,0x3000,0);
//sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
setSn_MR(sn,Sn_MR_UDP);
setSn_PORTR(sn, 0x3000);
setSn_CR(sn,Sn_CR_OPEN);
while(getSn_CR(sn) != 0);
while(getSn_SR(sn) != SOCK_UDP);
sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
};
#endif
setSn_CR(sn,Sn_CR_CLOSE); setSn_CR(sn,Sn_CR_CLOSE);
/* wait to process the command... */ /* wait to process the command... */
while( getSn_CR(sn) ); while( getSn_CR(sn) );
/* clear all interrupt of the socket. */ /* clear all interrupt of the socket. */
setSn_IR(sn, 0xFF); setSn_IR(sn, 0xFF);
//A20150401 : Release the sock_io_mode of socket n.
sock_io_mode &= ~(1<<sn);
//
sock_is_sending &= ~(1<<sn); sock_is_sending &= ~(1<<sn);
sock_remained_size[sn] = 0; sock_remained_size[sn] = 0;
sock_pack_info[sn] = 0; sock_pack_info[sn] = 0;
@ -176,13 +245,10 @@ int8_t listen(uint8_t sn)
setSn_CR(sn,Sn_CR_LISTEN); setSn_CR(sn,Sn_CR_LISTEN);
while(getSn_CR(sn)); while(getSn_CR(sn));
while(getSn_SR(sn) != SOCK_LISTEN) while(getSn_SR(sn) != SOCK_LISTEN)
{
if(getSn_CR(sn) == SOCK_CLOSED)
{ {
close(sn); close(sn);
return SOCKERR_SOCKCLOSED; return SOCKERR_SOCKCLOSED;
} }
}
return SOCK_OK; return SOCK_OK;
} }
@ -207,9 +273,6 @@ int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
if(port == 0) return SOCKERR_PORTZERO; if(port == 0) return SOCKERR_PORTZERO;
setSn_DIPR(sn,addr); setSn_DIPR(sn,addr);
setSn_DPORT(sn,port); setSn_DPORT(sn,port);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR(0);
#endif
setSn_CR(sn,Sn_CR_CONNECT); setSn_CR(sn,Sn_CR_CONNECT);
while(getSn_CR(sn)); while(getSn_CR(sn));
if(sock_io_mode & (1<<sn)) return SOCK_BUSY; if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
@ -218,9 +281,6 @@ int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
if (getSn_IR(sn) & Sn_IR_TIMEOUT) if (getSn_IR(sn) & Sn_IR_TIMEOUT)
{ {
setSn_IR(sn, Sn_IR_TIMEOUT); setSn_IR(sn, Sn_IR_TIMEOUT);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCKERR_TIMEOUT; return SOCKERR_TIMEOUT;
} }
@ -229,9 +289,6 @@ int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
return SOCKERR_SOCKCLOSED; return SOCKERR_SOCKCLOSED;
} }
} }
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
return SOCK_OK; return SOCK_OK;
} }
@ -272,12 +329,14 @@ int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
if(tmp & Sn_IR_SENDOK) if(tmp & Sn_IR_SENDOK)
{ {
setSn_IR(sn, Sn_IR_SENDOK); setSn_IR(sn, Sn_IR_SENDOK);
#if _WZICHIP_ == 5200 //M20150401 : Typing Error
//#if _WZICHIP_ == 5200
#if _WIZCHIP_ == 5200
if(getSn_TX_RD(sn) != sock_next_rd[sn]) if(getSn_TX_RD(sn) != sock_next_rd[sn])
{ {
setSn_CR(sn,Sn_CR_SEND); setSn_CR(sn,Sn_CR_SEND);
while(getSn_CR(sn)); while(getSn_CR(sn));
return SOCKERR_BUSY; return SOCK_BUSY;
} }
#endif #endif
sock_is_sending &= ~(1<<sn); sock_is_sending &= ~(1<<sn);
@ -307,11 +366,18 @@ int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
#if _WIZCHIP_ == 5200 #if _WIZCHIP_ == 5200
sock_next_rd[sn] = getSn_TX_RD(sn) + len; sock_next_rd[sn] = getSn_TX_RD(sn) + len;
#endif #endif
#if _WIZCHIP_ == 5300
setSn_TX_WRSR(sn,len);
#endif
setSn_CR(sn,Sn_CR_SEND); setSn_CR(sn,Sn_CR_SEND);
/* wait to process the command... */ /* wait to process the command... */
while(getSn_CR(sn)); while(getSn_CR(sn));
sock_is_sending |= (1 << sn); sock_is_sending |= (1 << sn);
return len; //M20150409 : Explicit Type Casting
//return len;
return (int32_t)len;
} }
@ -319,12 +385,26 @@ int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
{ {
uint8_t tmp = 0; uint8_t tmp = 0;
uint16_t recvsize = 0; uint16_t recvsize = 0;
//A20150601 : For integarating with W5300
#if _WIZCHIP_ == 5300
uint8_t head[2];
uint16_t mr;
#endif
//
CHECK_SOCKNUM(); CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP); CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKDATA(); CHECK_SOCKDATA();
recvsize = getSn_RxMAX(sn); recvsize = getSn_RxMAX(sn);
if(recvsize < len) len = recvsize; if(recvsize < len) len = recvsize;
//A20150601 : For Integrating with W5300
#if _WIZCHIP_ == 5300
//sock_pack_info[sn] = PACK_COMPLETED; // for clear
if(sock_remained_size[sn] == 0)
{
#endif
//
while(1) while(1)
{ {
recvsize = getSn_RX_RSR(sn); recvsize = getSn_RX_RSR(sn);
@ -349,11 +429,61 @@ int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
if(recvsize != 0) break; if(recvsize != 0) break;
}; };
#if _WIZCHIP_ == 5300
}
#endif
//A20150601 : For integrating with W5300
#if _WIZCHIP_ == 5300
if((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN))
{
mr = getMR();
if((getSn_MR(sn) & Sn_MR_ALIGN)==0)
{
wiz_recv_data(sn,head,2);
if(mr & MR_FS)
recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]);
else
recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]);
sock_pack_info[sn] = PACK_FIRST;
}
sock_remained_size[sn] = recvsize;
}
if(len > sock_remained_size[sn]) len = sock_remained_size[sn];
recvsize = len;
if(sock_pack_info[sn] & PACK_FIFOBYTE)
{
*buf = sock_remained_byte[sn];
buf++;
sock_pack_info[sn] &= ~(PACK_FIFOBYTE);
recvsize -= 1;
sock_remained_size[sn] -= 1;
}
if(recvsize != 0)
{
wiz_recv_data(sn, buf, recvsize);
setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn));
}
sock_remained_size[sn] -= recvsize;
if(sock_remained_size[sn] != 0)
{
sock_pack_info[sn] |= PACK_REMAINED;
if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE;
}
else sock_pack_info[sn] = PACK_COMPLETED;
if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0;
//len = recvsize;
#else
if(recvsize < len) len = recvsize; if(recvsize < len) len = recvsize;
wiz_recv_data(sn, buf, len); wiz_recv_data(sn, buf, len);
setSn_CR(sn,Sn_CR_RECV); setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn)); while(getSn_CR(sn));
return len; #endif
//M20150409 : Explicit Type Casting
//return len;
return (int32_t)len;
} }
int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
@ -368,6 +498,10 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
case Sn_MR_UDP: case Sn_MR_UDP:
case Sn_MR_MACRAW: case Sn_MR_MACRAW:
break; break;
#if ( _WIZCHIP_ < 5200 )
case Sn_MR_IPRAW:
break;
#endif
default: default:
return SOCKERR_SOCKMODE; return SOCKERR_SOCKMODE;
} }
@ -383,10 +517,14 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
//} //}
// //
//if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
if(taddr == 0) return SOCKERR_IPINVALID; if((taddr == 0) && (getSn_MR(sn)&Sn_MR_MACRAW != Sn_MR_MACRAW)) return SOCKERR_IPINVALID;
if(port == 0) return SOCKERR_PORTZERO; if((port == 0) && (getSn_MR(sn)&Sn_MR_MACRAW != Sn_MR_MACRAW)) return SOCKERR_PORTZERO;
tmp = getSn_SR(sn); tmp = getSn_SR(sn);
#if ( _WIZCHIP_ < 5200 )
if(tmp != SOCK_MACRAW && tmp != SOCK_UDP && tmp != SOCK_IPRAW) return SOCKERR_SOCKSTATUS;
#else
if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
#endif
setSn_DIPR(sn,addr); setSn_DIPR(sn,addr);
setSn_DPORT(sn,port); setSn_DPORT(sn,port);
@ -401,16 +539,24 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
}; };
wiz_send_data(sn, buf, len); wiz_send_data(sn, buf, len);
#if _WIZCHIP_ == 5200 // for W5200 ARP errata #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
setSUBR(0); getSIPR((uint8_t*)&taddr);
if(taddr == 0)
{
getSUBR((uint8_t*)&taddr);
setSUBR((uint8_t*)"\x00\x00\x00\x00");
}
else taddr = 0;
#endif #endif
//A20150601 : For W5300
#if _WIZCHIP_ == 5300
setSn_TX_WRSR(sn, len);
#endif
//
setSn_CR(sn,Sn_CR_SEND); setSn_CR(sn,Sn_CR_SEND);
/* wait to process the command... */ /* wait to process the command... */
while(getSn_CR(sn)); while(getSn_CR(sn));
#if _WIZCHIP_ == 5200 // for W5200 ARP errata
setSUBR((uint8_t*)"\x00\x00\x00\x00");
#endif
while(1) while(1)
{ {
tmp = getSn_IR(sn); tmp = getSn_IR(sn);
@ -424,23 +570,46 @@ int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t
else if(tmp & Sn_IR_TIMEOUT) else if(tmp & Sn_IR_TIMEOUT)
{ {
setSn_IR(sn, Sn_IR_TIMEOUT); setSn_IR(sn, Sn_IR_TIMEOUT);
//M20150409 : Fixed the lost of sign bits by type casting.
//len = (uint16_t)SOCKERR_TIMEOUT;
//break;
#if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
if(taddr) setSUBR((uint8_t*)&taddr);
#endif
return SOCKERR_TIMEOUT; return SOCKERR_TIMEOUT;
} }
//////////// ////////////
} }
return len; #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
if(taddr) setSUBR((uint8_t*)&taddr);
#endif
//M20150409 : Explicit Type Casting
//return len;
return (int32_t)len;
} }
int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
{ {
//M20150601 : For W5300
#if _WIZCHIP_ == 5300
uint16_t mr;
uint16_t mr1;
#else
uint8_t mr; uint8_t mr;
#endif
//
uint8_t head[8]; uint8_t head[8];
uint16_t pack_len=0; uint16_t pack_len=0;
CHECK_SOCKNUM(); CHECK_SOCKNUM();
//CHECK_SOCKMODE(Sn_MR_UDP); //CHECK_SOCKMODE(Sn_MR_UDP);
//A20150601
#if _WIZCHIP_ == 5300
mr1 = getMR();
#endif
switch((mr=getSn_MR(sn)) & 0x0F) switch((mr=getSn_MR(sn)) & 0x0F)
{ {
case Sn_MR_UDP: case Sn_MR_UDP:
@ -465,7 +634,8 @@ int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16
if(pack_len != 0) break; if(pack_len != 0) break;
}; };
} }
sock_pack_info[sn] = PACK_COMPLETED; //D20150601 : Move it to bottom
// sock_pack_info[sn] = PACK_COMPLETED;
switch (mr & 0x07) switch (mr & 0x07)
{ {
case Sn_MR_UDP : case Sn_MR_UDP :
@ -475,6 +645,22 @@ int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16
setSn_CR(sn,Sn_CR_RECV); setSn_CR(sn,Sn_CR_RECV);
while(getSn_CR(sn)); while(getSn_CR(sn));
// read peer's IP address, port number & packet length // read peer's IP address, port number & packet length
//A20150601 : For W5300
#if _WIZCHIP_ == 5300
if(mr1 & MR_FS)
{
addr[0] = head[1];
addr[1] = head[0];
addr[2] = head[3];
addr[3] = head[2];
*port = head[5];
*port = (*port << 8) + head[4];
sock_remained_size[sn] = head[7];
sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6];
}
else
{
#endif
addr[0] = head[0]; addr[0] = head[0];
addr[1] = head[1]; addr[1] = head[1];
addr[2] = head[2]; addr[2] = head[2];
@ -483,10 +669,24 @@ int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16
*port = (*port << 8) + head[5]; *port = (*port << 8) + head[5];
sock_remained_size[sn] = head[6]; sock_remained_size[sn] = head[6];
sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
#if _WIZCHIP_ == 5300
}
#endif
sock_pack_info[sn] = PACK_FIRST; sock_pack_info[sn] = PACK_FIRST;
} }
if(len < sock_remained_size[sn]) pack_len = len; if(len < sock_remained_size[sn]) pack_len = len;
else pack_len = sock_remained_size[sn]; else pack_len = sock_remained_size[sn];
//A20150601 : For W5300
len = pack_len;
#if _WIZCHIP_ == 5300
if(sock_pack_info[sn] & PACK_FIFOBYTE)
{
*buf++ = sock_remained_byte[sn];
pack_len -= 1;
sock_remained_size[sn] -= 1;
sock_pack_info[sn] &= ~PACK_FIFOBYTE;
}
#endif
// //
// Need to packet length check (default 1472) // Need to packet length check (default 1472)
// //
@ -500,7 +700,13 @@ int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16
while(getSn_CR(sn)); while(getSn_CR(sn));
// read peer's IP address, port number & packet length // read peer's IP address, port number & packet length
sock_remained_size[sn] = head[0]; sock_remained_size[sn] = head[0];
sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1]; sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1] -2;
#if _WIZCHIP_ == W5300
if(sock_remained_size[sn] & 0x01)
sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4;
else
sock_remained_size[sn] -= 4;
#endif
if(sock_remained_size[sn] > 1514) if(sock_remained_size[sn] > 1514)
{ {
close(sn); close(sn);
@ -524,7 +730,9 @@ int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16
addr[2] = head[2]; addr[2] = head[2];
addr[3] = head[3]; addr[3] = head[3];
sock_remained_size[sn] = head[4]; sock_remained_size[sn] = head[4];
sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; //M20150401 : For Typing Error
//sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5];
sock_pack_info[sn] = PACK_FIRST; sock_pack_info[sn] = PACK_FIRST;
} }
// //
@ -544,11 +752,23 @@ int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16
/* wait to process the command... */ /* wait to process the command... */
while(getSn_CR(sn)) ; while(getSn_CR(sn)) ;
sock_remained_size[sn] -= pack_len; sock_remained_size[sn] -= pack_len;
//M20140501 : replace 0x01 with PACK_REMAINED //M20150601 :
//if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED; if(sock_remained_size[sn] != 0)
{
sock_pack_info[sn] |= PACK_REMAINED;
#if _WIZCHIP_ == 5300
if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE;
#endif
}
else sock_pack_info[sn] = PACK_COMPLETED;
#if _WIZCHIP_ == 5300
pack_len = len;
#endif
// //
return pack_len; //M20150409 : Explicit Type Casting
//return pack_len;
return (int32_t)pack_len;
} }
@ -583,6 +803,7 @@ int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
case CS_GET_INTERRUPT: case CS_GET_INTERRUPT:
*((uint8_t*)arg) = getSn_IR(sn); *((uint8_t*)arg) = getSn_IR(sn);
break; break;
#if _WIZCHIP_ != 5100
case CS_SET_INTMASK: case CS_SET_INTMASK:
if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
setSn_IMR(sn,*(uint8_t*)arg); setSn_IMR(sn,*(uint8_t*)arg);
@ -590,6 +811,7 @@ int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
case CS_GET_INTMASK: case CS_GET_INTMASK:
*((uint8_t*)arg) = getSn_IMR(sn); *((uint8_t*)arg) = getSn_IMR(sn);
break; break;
#endif
default: default:
return SOCKERR_ARG; return SOCKERR_ARG;
} }
@ -694,7 +916,11 @@ int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
*(uint16_t*)arg = sock_remained_size[sn]; *(uint16_t*)arg = sock_remained_size[sn];
break; break;
case SO_PACKINFO: case SO_PACKINFO:
CHECK_SOCKMODE(Sn_MR_TCP); //CHECK_SOCKMODE(Sn_MR_TCP);
#if _WIZCHIP_ != 5300
if((getSn_MR(sn) == Sn_MR_TCP))
return SOCKERR_SOCKMODE;
#endif
*(uint8_t*)arg = sock_pack_info[sn]; *(uint8_t*)arg = sock_pack_info[sn];
break; break;
default: default:

View File

@ -96,7 +96,7 @@
#define SOCK_ERROR 0 #define SOCK_ERROR 0
#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number #define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number
#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option #define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option
#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized #define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP
#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. #define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed.
#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. #define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation.
#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag #define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag
@ -113,16 +113,21 @@
/* /*
* SOCKET FLAG * SOCKET FLAG
*/ */
#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In \ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet #define SF_ETHER_OWN (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet
#define SF_IGMP_VER2 (Sn_MR_MC) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2. #define SF_IGMP_VER2 (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2.
#define SF_TCP_NODELAY (Sn_MR_ND) ///< In \ref Sn_MR_TCP, Use to nodelayed ack. #define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack.
#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In \ref Sn_MR_UDP, Enable multicast mode. #define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode.
#if _WIZCHIP_ == 5500 #if _WIZCHIP_ == 5500
#define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In \ref Sn_MR_UDP or \ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500 #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500
#define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In \ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500 #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500
#define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In \ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500 #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500
#define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500 #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500
#endif
//A201505 : For W5300
#if _WIZCHIP_ == 5300
#define SF_TCP_ALIGN 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN
#endif #endif
#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). #define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket().
@ -130,9 +135,12 @@
/* /*
* UDP & MACRAW Packet Infomation * UDP & MACRAW Packet Infomation
*/ */
#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. #define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When W5300, This flag can be applied)
#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. #define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. (When W5300, This flag can be applied)
#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. #define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. (When W5300, This flag can be applied)
//A20150601 : For Integrating with W5300
#define PACK_FIFOBYTE 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR.
//
/** /**
* @ingroup WIZnet_socket_APIs * @ingroup WIZnet_socket_APIs
@ -341,7 +349,9 @@ typedef enum
SIK_RECEIVED = (1 << 2), ///< data received SIK_RECEIVED = (1 << 2), ///< data received
SIK_TIMEOUT = (1 << 3), ///< timeout occurred SIK_TIMEOUT = (1 << 3), ///< timeout occurred
SIK_SENT = (1 << 4), ///< send ok SIK_SENT = (1 << 4), ///< send ok
SIK_ALL = 0x1F, ///< all interrupt //M20150410 : Remove the comma of last member
//SIK_ALL = 0x1F, ///< all interrupt
SIK_ALL = 0x1F ///< all interrupt
}sockint_kind; }sockint_kind;
/** /**
@ -356,8 +366,10 @@ typedef enum
CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory
CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind
CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind
CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind #if _WIZCHIP_ > 5100
CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, Not supported in W5100
CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind, Not supported in W5100
#endif
}ctlsock_type; }ctlsock_type;
@ -368,15 +380,15 @@ typedef enum
typedef enum typedef enum
{ {
SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket(). SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket().
SO_TTL, ///< Set/Get TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() )
SO_TOS, ///< Set/Get TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() )
SO_MSS, ///< Set/Get MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() )
SO_DESTIP, ///< Set/Get the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() ) SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() )
SO_DESTPORT, ///< Set/Get the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() ) SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() )
#if _WIZCHIP_ != 5100 #if _WIZCHIP_ != 5100
SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode, Not supported in W5100
#if _WIZCHIP_ > 5200 #if _WIZCHIP_ > 5200
SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode, Not supported in W5100, W5200
#endif #endif
#endif #endif
SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR()

View File

@ -10,7 +10,7 @@
//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. //! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
//! >> https://github.com/Wiznet/ioLibrary_Driver //! >> https://github.com/Wiznet/ioLibrary_Driver
//! <2014/05/01> V1.0.1 Refer to M20140501 //! <2014/05/01> V1.0.1 Refer to M20140501
//! 1. Explicit type casting in wizchip_bus_readbyte() & wizchip_bus_writebyte() //! 1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata()
// Issued by Mathias ClauBen. // Issued by Mathias ClauBen.
//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t* //! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
//! For remove the warning when pointer type size is not 32bit. //! For remove the warning when pointer type size is not 32bit.
@ -53,77 +53,101 @@
// //
#include "wizchip_conf.h" #include "wizchip_conf.h"
/////////////
//M20150401 : Remove ; in the default callback function such as wizchip_cris_enter(), wizchip_cs_select() and etc.
/////////////
/** /**
* @brief Default function to enable interrupt. * @brief Default function to enable interrupt.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
void wizchip_cris_enter(void) {}; //void wizchip_cris_enter(void) {};
void wizchip_cris_enter(void) {}
/** /**
* @brief Default function to disable interrupt. * @brief Default function to disable interrupt.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
void wizchip_cris_exit(void) {}; //void wizchip_cris_exit(void) {};
void wizchip_cris_exit(void) {}
/** /**
* @brief Default function to select chip. * @brief Default function to select chip.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
void wizchip_cs_select(void) {}; //void wizchip_cs_select(void) {};
void wizchip_cs_select(void) {}
/** /**
* @brief Default function to deselect chip. * @brief Default function to deselect chip.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
void wizchip_cs_deselect(void) {}; //void wizchip_cs_deselect(void) {};
void wizchip_cs_deselect(void) {}
/** /**
* @brief Default function to read in direct or indirect interface. * @brief Default function to read in direct or indirect interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
//M20140501 : Explict pointer type casting //M20150601 : Rename the function for integrating with W5300
//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *) AddrSel); }; //uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }
uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }; iodata_t wizchip_bus_readdata(uint32_t AddrSel) { return * ((volatile iodata_t *)((ptrdiff_t) AddrSel)); }
/** /**
* @brief Default function to write in direct or indirect interface. * @brief Default function to write in direct or indirect interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
//M20150601 : Rename the function for integrating with W5300
//M20140501 : Explict pointer type casting //void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }
//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*) AddrSel) = wb; }; void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { *((volatile iodata_t*)((ptrdiff_t)AddrSel)) = wb; }
void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; };
/** /**
* @brief Default function to read in SPI interface. * @brief Default function to read in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
uint8_t wizchip_spi_readbyte(void) {return 0;}; //uint8_t wizchip_spi_readbyte(void) {return 0;};
uint8_t wizchip_spi_readbyte(void) {return 0;}
/** /**
* @brief Default function to write in SPI interface. * @brief Default function to write in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
void wizchip_spi_writebyte(uint8_t wb) {}; //void wizchip_spi_writebyte(uint8_t wb) {};
void wizchip_spi_writebyte(uint8_t wb) {}
/** /**
* @brief Default function to burst read in SPI interface. * @brief Default function to burst read in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; //void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {};
void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}
/** /**
* @brief Default function to burst write in SPI interface. * @brief Default function to burst write in SPI interface.
* @note This function help not to access wrong address. If you do not describe this function or register any functions, * @note This function help not to access wrong address. If you do not describe this function or register any functions,
* null function is called. * null function is called.
*/ */
void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; //void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {};
void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}
/** /**
* @\ref _WIZCHIP instance * @\ref _WIZCHIP instance
*/ */
//
//M20150401 : For a compiler didnot support a member of structure
// Replace the assignment of struct members with the assingment of array
//
/*
_WIZCHIP WIZCHIP = _WIZCHIP WIZCHIP =
{ {
.id = _WIZCHIP_ID_, .id = _WIZCHIP_ID_,
@ -137,6 +161,24 @@ _WIZCHIP WIZCHIP =
// .IF.SPI._read_byte = wizchip_spi_readbyte, // .IF.SPI._read_byte = wizchip_spi_readbyte,
// .IF.SPI._write_byte = wizchip_spi_writebyte // .IF.SPI._write_byte = wizchip_spi_writebyte
}; };
*/
_WIZCHIP WIZCHIP =
{
_WIZCHIP_IO_MODE_,
_WIZCHIP_ID_ ,
wizchip_cris_enter,
wizchip_cris_exit,
wizchip_cs_select,
wizchip_cs_deselect,
//M20150601 : Rename the function
//wizchip_bus_readbyte,
//wizchip_bus_writebyte
wizchip_bus_readdata,
wizchip_bus_writedata,
// wizchip_spi_readbyte,
// wizchip_spi_writebyte
};
static uint8_t _DNS_[4]; // DNS server ip address static uint8_t _DNS_[4]; // DNS server ip address
static dhcp_mode _DHCP_; // DHCP mode static dhcp_mode _DHCP_; // DHCP mode
@ -169,10 +211,13 @@ void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void))
} }
} }
void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)) //M20150515 : For integrating with W5300
//void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb))
void reg_wizchip_bus_cbfunc(iodata_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb))
{ {
while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_));
//M20150601 : Rename call back function for integrating with W5300
/*
if(!bus_rb || !bus_wb) if(!bus_rb || !bus_wb)
{ {
WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte;
@ -183,6 +228,17 @@ void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint
WIZCHIP.IF.BUS._read_byte = bus_rb; WIZCHIP.IF.BUS._read_byte = bus_rb;
WIZCHIP.IF.BUS._write_byte = bus_wb; WIZCHIP.IF.BUS._write_byte = bus_wb;
} }
*/
if(!bus_rb || !bus_wb)
{
WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata;
WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata;
}
else
{
WIZCHIP.IF.BUS._read_data = bus_rb;
WIZCHIP.IF.BUS._write_data = bus_wb;
}
} }
void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)) void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
@ -220,7 +276,9 @@ void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), vo
int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
{ {
#if _WIZCHIP_ == 5200 || _WIZCHIP_ == 5500
uint8_t tmp = 0; uint8_t tmp = 0;
#endif
uint8_t* ptmp[2] = {0,0}; uint8_t* ptmp[2] = {0,0};
switch(cwtype) switch(cwtype)
{ {
@ -246,7 +304,9 @@ int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
case CW_GET_INTRMASK: case CW_GET_INTRMASK:
*((intr_kind*)arg) = wizchip_getinterruptmask(); *((intr_kind*)arg) = wizchip_getinterruptmask();
break; break;
#if _WIZCHIP_ > 5100 //M20150601 : This can be supported by W5200, W5500
//#if _WIZCHIP_ > 5100
#if (_WIZCHIP_ == 5200 || _WIZCHIP_ == 5500)
case CW_SET_INTRTIME: case CW_SET_INTRTIME:
setINTLEVEL(*(uint16_t*)arg); setINTLEVEL(*(uint16_t*)arg);
break; break;
@ -277,6 +337,7 @@ int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
case CW_SET_PHYPOWMODE: case CW_SET_PHYPOWMODE:
return wizphy_setphypmode(*(uint8_t*)arg); return wizphy_setphypmode(*(uint8_t*)arg);
#endif #endif
#if _WIZCHIP_ == 5200 || _WIZCHIP_ == 5500
case CW_GET_PHYPOWMODE: case CW_GET_PHYPOWMODE:
tmp = wizphy_getphypmode(); tmp = wizphy_getphypmode();
if((int8_t)tmp == -1) return -1; if((int8_t)tmp == -1) return -1;
@ -287,6 +348,7 @@ int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
if((int8_t)tmp == -1) return -1; if((int8_t)tmp == -1) return -1;
*(uint8_t*)arg = tmp; *(uint8_t*)arg = tmp;
break; break;
#endif
default: default:
return -1; return -1;
} }
@ -326,10 +388,21 @@ void wizchip_sw_reset(void)
{ {
uint8_t gw[4], sn[4], sip[4]; uint8_t gw[4], sn[4], sip[4];
uint8_t mac[6]; uint8_t mac[6];
//A20150601
#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_
uint16_t mr = (uint16_t)getMR();
setMR(mr | MR_IND);
#endif
//
getSHAR(mac); getSHAR(mac);
getGAR(gw); getSUBR(sn); getSIPR(sip); getGAR(gw); getSUBR(sn); getSIPR(sip);
setMR(MR_RST); setMR(MR_RST);
getMR(); // for delay getMR(); // for delay
//A2015051 : For indirect bus mode
#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_
setMR(mr | MR_IND);
#endif
//
setSHAR(mac); setSHAR(mac);
setGAR(gw); setGAR(gw);
setSUBR(sn); setSUBR(sn);
@ -344,18 +417,44 @@ int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize)
if(txsize) if(txsize)
{ {
tmp = 0; tmp = 0;
//M20150601 : For integrating with W5300
#if _WIZCHIP_ == 5300
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
{
if(txsize[i] >= 64) return -1; //No use 64KB even if W5300 support max 64KB memory allocation
tmp += txsize[i];
if(tmp > 128) return -1;
}
if(tmp % 8) return -1;
#else
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
{
tmp += txsize[i]; tmp += txsize[i];
if(tmp > 16) return -1; if(tmp > 16) return -1;
}
#endif
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
setSn_TXBUF_SIZE(i, txsize[i]); setSn_TXBUF_SIZE(i, txsize[i]);
} }
if(rxsize) if(rxsize)
{ {
tmp = 0; tmp = 0;
#if _WIZCHIP_ == 5300
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
{
if(rxsize[i] >= 64) return -1; //No use 64KB even if W5300 support max 64KB memory allocation
tmp += rxsize[i];
if(tmp > 128) return -1;
}
if(tmp % 8) return -1;
#else
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
{
tmp += rxsize[i]; tmp += rxsize[i];
if(tmp > 16) return -1; if(tmp > 16) return -1;
}
#endif
for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
setSn_RXBUF_SIZE(i, rxsize[i]); setSn_RXBUF_SIZE(i, rxsize[i]);
} }
@ -380,6 +479,9 @@ void wizchip_clrinterrupt(intr_kind intr)
#if _WIZCHIP_ == 5100 #if _WIZCHIP_ == 5100
ir |= sir; ir |= sir;
setIR(ir); setIR(ir);
//A20150601 : For integrating with W5300
#elif _WIZCHIP_ == 5300
setIR( ((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF)) );
#else #else
setIR(ir); setIR(ir);
setSIR(sir); setSIR(sir);
@ -393,13 +495,20 @@ intr_kind wizchip_getinterrupt(void)
uint16_t ret = 0; uint16_t ret = 0;
#if _WIZCHIP_ == 5100 #if _WIZCHIP_ == 5100
ir = getIR(); ir = getIR();
sir = ir 0x0F; sir = ir & 0x0F;
//A20150601 : For integrating with W5300
#elif _WIZCHIP_ == 5300
ret = getIR();
ir = (uint8_t)(ret >> 8);
sir = (uint8_t)ret;
#else #else
ir = getIR(); ir = getIR();
sir = getSIR(); sir = getSIR();
#endif #endif
#if _WIZCHIP_ < 5500 //M20150601 : For Integrating with W5300
//#if _WIZCHIP_ < 5500
#if _WIZCHIP_ < 5200
ir &= ~(1<<4); // IK_WOL ir &= ~(1<<4); // IK_WOL
#endif #endif
#if _WIZCHIP_ == 5200 #if _WIZCHIP_ == 5200
@ -421,13 +530,13 @@ void wizchip_setinterruptmask(intr_kind intr)
imr &= ~(1 << 6); imr &= ~(1 << 6);
#endif #endif
#if _WIZCHIP_ < 5200
simr &= 0x0F;
#endif
#if _WIZCHIP_ == 5100 #if _WIZCHIP_ == 5100
simr &= 0x0F;
imr |= simr; imr |= simr;
setIMR(imr); setIMR(imr);
//A20150601 : For integrating with W5300
#elif _WIZCHIP_ == 5300
setIMR( ((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF)) );
#else #else
setIMR(imr); setIMR(imr);
setSIMR(simr); setSIMR(simr);
@ -441,7 +550,12 @@ intr_kind wizchip_getinterruptmask(void)
uint16_t ret = 0; uint16_t ret = 0;
#if _WIZCHIP_ == 5100 #if _WIZCHIP_ == 5100
imr = getIMR(); imr = getIMR();
simr = imr 0x0F; simr = imr & 0x0F;
//A20150601 : For integrating with W5300
#elif _WIZCHIP_ == 5300
ret = getIMR();
imr = (uint8_t)(ret >> 8);
simr = (uint8_t)ret;
#else #else
imr = getIMR(); imr = getIMR();
simr = getSIMR(); simr = getSIMR();

View File

@ -57,10 +57,12 @@
#include <stdint.h> #include <stdint.h>
/** /**
* @brief Select WIZCHIP. * @brief Select WIZCHIP.
* @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n * @todo You should select one, \b 5100, \b 5200, \b 5300, \b 5500 or etc. \n\n
* ex> <code> #define \_WIZCHIP_ 5500 </code> * ex> <code> #define \_WIZCHIP_ 5500 </code>
*/ */
#define _WIZCHIP_ 5500 // 5100, 5200, 5500 #ifndef _WIZCHIP_
#define _WIZCHIP_ 5500 // 5100, 5200, 5300, 5500
#endif
#define _WIZCHIP_IO_MODE_NONE_ 0x0000 #define _WIZCHIP_IO_MODE_NONE_ 0x0000
#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ #define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */
@ -83,19 +85,27 @@
* @brief Define interface mode. * @brief Define interface mode.
* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
*/ */
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ // #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ // #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
//A20150601 : Define the unit of IO DATA.
typedef uint8_t iodata_t;
//A20150401 : Indclude W5100.h file
#include "W5100/w5100.h"
#elif (_WIZCHIP_ == 5200) #elif (_WIZCHIP_ == 5200)
#define _WIZCHIP_ID_ "W5200\0" #define _WIZCHIP_ID_ "W5200\0"
/** /**
* @brief Define interface mode. * @brief Define interface mode.
* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
*/ */
#ifndef _WIZCHIP_IO_MODE_
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ // #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
#endif
//A20150601 : Define the unit of IO DATA.
typedef uint8_t iodata_t;
#include "W5200/w5200.h" #include "W5200/w5200.h"
#elif (_WIZCHIP_ == 5500) #elif (_WIZCHIP_ == 5500)
#define _WIZCHIP_ID_ "W5500\0" #define _WIZCHIP_ID_ "W5500\0"
@ -113,9 +123,41 @@
* ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code> * ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code>
* *
*/ */
#ifndef _WIZCHIP_IO_MODE_
//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_
#endif
//A20150601 : Define the unit of IO DATA.
typedef uint8_t iodata_t;
#include "W5500/w5500.h" #include "W5500/w5500.h"
#elif ( _WIZCHIP_ == 5300)
#define _WIZCHIP_ID_ "W5300\0"
/**
* @brief Define interface mode.
* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
*/
#ifndef _WIZCHIP_IO_MODE_
// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
#endif
//A20150601 : Define the unit and bus width of IO DATA.
/**
* @brief Select the data width 8 or 16 bits.
* @todo you should select the bus width. Select one of 8 or 16.
*/
#ifndef _WIZCHIP_IO_BUS_WIDTH_
#define _WIZCHIP_IO_BUS_WIDTH_ 8 // 16
#endif
#if _WIZCHIP_IO_BUS_WIDTH_ == 8
typedef uint8_t iodata_t;
#elif _WIZCHIP_IO_BUS_WIDTH_ == 16
typedef uint16_t iodata_t;
#else
#error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16."
#endif
//
#include "W5300/w5300.h"
#else #else
#error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!"
#endif #endif
@ -130,9 +172,13 @@
* @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n
* ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code> * ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code>
*/ */
#define _WIZCHIP_IO_BASE_ 0x00000000 // #ifndef _WIZCHIP_IO_BASE_
#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000
#endif
#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS //M20150401 : Typing Error
//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS
#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_
#ifndef _WIZCHIP_IO_BASE_ #ifndef _WIZCHIP_IO_BASE_
#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map."
#endif #endif
@ -165,7 +211,7 @@ typedef struct __WIZCHIP
void (*_exit) (void); ///< critial section exit void (*_exit) (void); ///< critial section exit
}CRIS; }CRIS;
/** /**
* The set of @ref\_WIZCHIP_ select control callback func. * The set of @ref \_WIZCHIP_ select control callback func.
*/ */
struct _CS struct _CS
{ {
@ -180,11 +226,18 @@ typedef struct __WIZCHIP
/** /**
* For BUS interface IO * For BUS interface IO
*/ */
//M20156501 : Modify the function name for integrating with W5300
//struct
//{
// uint8_t (*_read_byte) (uint32_t AddrSel);
// void (*_write_byte) (uint32_t AddrSel, uint8_t wb);
//}BUS;
struct struct
{ {
uint8_t (*_read_byte) (uint32_t AddrSel); iodata_t (*_read_data) (uint32_t AddrSel);
void (*_write_byte) (uint32_t AddrSel, uint8_t wb); void (*_write_data) (uint32_t AddrSel, iodata_t wb);
}BUS; }BUS;
/** /**
* For SPI interface IO * For SPI interface IO
*/ */
@ -218,15 +271,19 @@ typedef enum
CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt. CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt.
CW_GET_ID, ///< Gets WIZCHIP name. CW_GET_ID, ///< Gets WIZCHIP name.
#if _WIZCHIP_ == 5500 //D20150601 : For no modification your application code
CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5000 //#if _WIZCHIP_ == 5500
CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500
CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000
CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only W5000 CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only W5500
CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5000 CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500
CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when PHYSTATUS.OPMD == 1. Valid Only W5500 CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when PHYSTATUS.OPMD == 1. Valid Only W5500
#endif //#endif
CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal //D20150601 : For no modification your application code
CW_GET_PHYLINK ///< Get PHY Link status //#if _WIZCHIP_ == 5200 || _WIZCHIP_ == 5500
CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only W5100, W5200
CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200
//#endif
}ctlwizchip_type; }ctlwizchip_type;
/** /**
@ -251,8 +308,10 @@ typedef enum
*/ */
typedef enum typedef enum
{ {
#if _WIZCHIP_ > 5200 #if _WIZCHIP_ == 5500
IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500.
#elif _WIZCHIP_ == 5300
IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU)
#endif #endif
IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected
@ -389,7 +448,9 @@ void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void));
*or register your functions. *or register your functions.
*@note If you do not describe or register, null function is called. *@note If you do not describe or register, null function is called.
*/ */
void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)); //M20150601 : For integrating with W5300
//void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb));
void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb));
/** /**
*@brief Registers call back function for SPI interface. *@brief Registers call back function for SPI interface.
@ -547,17 +608,17 @@ netmode_type wizchip_getnetmode(void);
/** /**
* @ingroup extra_functions * @ingroup extra_functions
* @brief Set retry time value(@ref RTR) and retry count(@ref RCR). * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_).
* @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.
* @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.
*/ */
void wizchip_settimeout(wiz_NetTimeout* nettime); void wizchip_settimeout(wiz_NetTimeout* nettime);
/** /**
* @ingroup extra_functions * @ingroup extra_functions
* @brief Get retry time value(@ref RTR) and retry count(@ref RCR). * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_).
* @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.
* @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.
*/ */
void wizchip_gettimeout(wiz_NetTimeout* nettime); void wizchip_gettimeout(wiz_NetTimeout* nettime);

View File

@ -1,103 +1,37 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <stdarg.h>
#include "stdio_private.h"
#include "socket.h"
#include "ftpc.h" #include "ftpc.h"
#include "mmcHandler.h"
/* FTP Responses */
#define R_150 150 /* File status ok; opening data conn */
#define R_200 200 /* 'Generic' command ok */
#define R_220 220 /* Service ready for new user. */
#define R_226 226 /* Closing data connection. File transfer/abort successful */
#define R_227 227 /* Entering passive mode (h1,h2,h3,h4,p1,p2) */
#define R_230 230 /* User logged in, proceed */
#define R_331 331 /* User name okay, need password. */
#define TransferAscii 0x41
#define TransferBinary 0x49
#define ConnectActive 1
#define ConnectPassive 0
un_l2cval remote_ip; un_l2cval remote_ip;
uint16_t remote_port; uint16_t remote_port;
un_l2cval local_ip; un_l2cval local_ip;
uint16_t local_port; uint16_t local_port;
uint8_t connect_state_controlc = 0; uint8_t connect_state_control_ftpc = 0;
uint8_t connect_state_datac = 0; uint8_t connect_state_data_ftpc = 0;
uint8_t gModeActivePassiveflag = 0; uint8_t gModeActivePassiveflag = 0;
struct ftpd ftp; uint8_t FTP_destip[4] = {192, 168, 10, 230}; // For FTP client examples; destination network info
uint16_t FTP_destport = 21; // For FTP client examples; destination network info
enum CommandFirst {
f_nocmd,
f_dir,
f_put,
f_get,
};
enum CommandSecond {
s_nocmd,
s_dir,
s_put,
s_get,
};
struct Command {
enum CommandFirst First;
enum CommandSecond Second;
};
struct Command Command;
int current_yearc = 2014;
int current_monthc = 12;
int current_dayc = 31;
int current_hourc = 10;
int current_minc = 10;
int current_secc = 30;
uint8_t gMenuStart = 0; uint8_t gMenuStart = 0;
uint8_t gDataSockReady = 0; uint8_t gDataSockReady = 0;
uint8_t gDataPutGetStart = 0; uint8_t gDataPutGetStart = 0;
uint8_t gModeAsciiBinary = 0;
uint8_t gModeActivePassive = ConnectPassive;
static uint8_t gMsgBuf[20]={0,}; static uint8_t gMsgBuf[20]={0,};
// For FTP client examples; destination network info struct ftpc ftpc;
uint8_t FTP_destip[4] = {192, 168, 0, 230}; struct Command Command;
uint16_t FTP_destport = 21;
extern int Board_UARTGetCharBlocking(void);
uint8_t* User_Keyboard_MSG()
{
uint8_t i=0;
do{
gMsgBuf[i] = Board_UARTGetCharBlocking();
i++;
}while(gMsgBuf[i-1]!=0x0d);
gMsgBuf[i-1]=0;
return gMsgBuf;
}
void ftpc_init(uint8_t * src_ip) void ftpc_init(uint8_t * src_ip)
{ {
ftp.state = FTPS_NOT_LOGIN; ftpc.dsock_mode = ACTIVE_MODE;
ftp.dsock_mode = ACTIVE_MODE;
local_ip.cVal[0] = src_ip[0]; local_ip.cVal[0] = src_ip[0];
local_ip.cVal[1] = src_ip[1]; local_ip.cVal[1] = src_ip[1];
local_ip.cVal[2] = src_ip[2]; local_ip.cVal[2] = src_ip[2];
local_ip.cVal[3] = src_ip[3]; local_ip.cVal[3] = src_ip[3];
local_port = 35000; local_port = 35000;
strcpy(ftp.workingdir, "/"); strcpy(ftpc.workingdir, "/");
socket(CTRL_SOCK, Sn_MR_TCP, IPPORT_FTP, 0x0); socket(CTRL_SOCK, Sn_MR_TCP, FTP_destport, 0x0);
} }
uint8_t ftpc_run(uint8_t * dbuf) uint8_t ftpc_run(uint8_t * dbuf)
{ {
#ifndef Need_UARTGetCharBlocking_func
uint16_t size = 0; uint16_t size = 0;
long ret = 0; long ret = 0;
uint32_t send_byte, recv_byte; uint32_t send_byte, recv_byte;
@ -111,10 +45,10 @@ uint8_t ftpc_run(uint8_t * dbuf)
switch(getSn_SR(CTRL_SOCK)) switch(getSn_SR(CTRL_SOCK))
{ {
case SOCK_ESTABLISHED : case SOCK_ESTABLISHED :
if(!connect_state_controlc){ if(!connect_state_control_ftpc){
printf("%d:FTP Connected\r\n", CTRL_SOCK); printf("%d:FTP Connected\r\n", CTRL_SOCK);
strcpy(ftp.workingdir, "/"); strcpy(ftpc.workingdir, "/");
connect_state_controlc = 1; connect_state_control_ftpc = 1;
} }
if(gMenuStart){ if(gMenuStart){
gMenuStart = 0; gMenuStart = 0;
@ -123,16 +57,18 @@ uint8_t ftpc_run(uint8_t * dbuf)
printf("----------------------------------------\r\n"); printf("----------------------------------------\r\n");
printf("1> View FTP Server Directory\r\n"); printf("1> View FTP Server Directory\r\n");
printf("2> View My Directory\r\n"); printf("2> View My Directory\r\n");
printf("3> Sets the type of file to be transferred. Current state : %s\r\n", (gModeAsciiBinary==TransferAscii)?"Ascii":"Binary"); printf("3> Sets the type of file to be transferred. Current state : %s\r\n", (ftpc.type==ASCII_TYPE)?"Ascii":"Binary");
printf("4> Sets Data Connection. Current state : %s\r\n", (gModeActivePassive==ConnectActive)?"Active":"Passive"); printf("4> Sets Data Connection. Current state : %s\r\n", (ftpc.dsock_mode==ACTIVE_MODE)?"Active":"Passive");
printf("5> Put File to Server\r\n"); printf("5> Put File to Server\r\n");
printf("6> Get File from Server\r\n"); printf("6> Get File from Server\r\n");
#if defined(F_FILESYSTEM)
printf("7> Delete My File\r\n"); printf("7> Delete My File\r\n");
#endif
printf("----------------------------------------\r\n"); printf("----------------------------------------\r\n");
while(1){ while(1){
msg_c=Board_UARTGetCharBlocking(); msg_c=ftp_getc();
if(msg_c=='1'){ if(msg_c=='1'){
if(gModeActivePassive==ConnectPassive){ if(ftpc.dsock_mode==PASSIVE_MODE){
sprintf(dat,"PASV\r\n"); sprintf(dat,"PASV\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_dir; Command.First = f_dir;
@ -151,7 +87,7 @@ uint8_t ftpc_run(uint8_t * dbuf)
break; break;
} }
else if(msg_c=='5'){ else if(msg_c=='5'){
if(gModeActivePassive==ConnectPassive){ if(ftpc.dsock_mode==PASSIVE_MODE){
sprintf(dat,"PASV\r\n"); sprintf(dat,"PASV\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_put; Command.First = f_put;
@ -169,7 +105,7 @@ uint8_t ftpc_run(uint8_t * dbuf)
} }
} }
else if(msg_c=='6'){ else if(msg_c=='6'){
if(gModeActivePassive==ConnectPassive){ if(ftpc.dsock_mode==PASSIVE_MODE){
sprintf(dat,"PASV\r\n"); sprintf(dat,"PASV\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
Command.First = f_get; Command.First = f_get;
@ -187,10 +123,14 @@ uint8_t ftpc_run(uint8_t * dbuf)
} }
} }
else if(msg_c=='2'){ else if(msg_c=='2'){
scan_files(ftp.workingdir, dbuf, (int *)&size); #if defined(F_FILESYSTEM)
scan_files(ftpc.workingdir, dbuf, (int *)&size);
printf("\r\n%s\r\n", dbuf); printf("\r\n%s\r\n", dbuf);
getMountedMemorySize(SPI_FLASHM, &totalSize, &availableSize); #else
printf(" - Available Memory Size : %ld kB / %ld kB ( %ld kB is used )\r\n", availableSize, totalSize, (totalSize - availableSize)); if (strncmp(ftpc.workingdir, "/$Recycle.Bin", sizeof("/$Recycle.Bin")) != 0)
size = sprintf(dbuf, "drwxr-xr-x 1 ftp ftp 0 Dec 31 2014 $Recycle.Bin\r\n-rwxr-xr-x 1 ftp ftp 512 Dec 31 2014 test.txt\r\n");
printf("\r\n%s\r\n", dbuf);
#endif
gMenuStart = 1; gMenuStart = 1;
break; break;
} }
@ -198,16 +138,16 @@ uint8_t ftpc_run(uint8_t * dbuf)
printf("1> ASCII\r\n"); printf("1> ASCII\r\n");
printf("2> BINARY\r\n"); printf("2> BINARY\r\n");
while(1){ while(1){
msg_c=Board_UARTGetCharBlocking(); msg_c=ftp_getc();
if(msg_c=='1'){ if(msg_c=='1'){
sprintf(dat,"TYPE %c\r\n", TransferAscii); sprintf(dat,"TYPE %c\r\n", TransferAscii);
gModeAsciiBinary = TransferAscii; ftpc.type = ASCII_TYPE;
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
} }
else if(msg_c=='2'){ else if(msg_c=='2'){
sprintf(dat,"TYPE %c\r\n", TransferBinary); sprintf(dat,"TYPE %c\r\n", TransferBinary);
gModeAsciiBinary = TransferBinary; ftpc.type = IMAGE_TYPE;
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
} }
@ -221,13 +161,13 @@ uint8_t ftpc_run(uint8_t * dbuf)
printf("1> ACTIVE\r\n"); printf("1> ACTIVE\r\n");
printf("2> PASSIVE\r\n"); printf("2> PASSIVE\r\n");
while(1){ while(1){
msg_c=Board_UARTGetCharBlocking(); msg_c=ftp_getc();
if(msg_c=='1'){ if(msg_c=='1'){
gModeActivePassive = ConnectActive; ftpc.dsock_mode=ACTIVE_MODE;
break; break;
} }
else if(msg_c=='2'){ else if(msg_c=='2'){
gModeActivePassive = ConnectPassive; ftpc.dsock_mode=PASSIVE_MODE;
break; break;
} }
else{ else{
@ -237,10 +177,11 @@ uint8_t ftpc_run(uint8_t * dbuf)
gMenuStart = 1; gMenuStart = 1;
break; break;
} }
#if defined(F_FILESYSTEM)
else if(msg_c=='7'){ else if(msg_c=='7'){
printf(">del filename?"); printf(">del filename?");
sprintf(ftp.filename, "/%s\r\n", User_Keyboard_MSG()); sprintf(ftpc.filename, "/%s\r\n", User_Keyboard_MSG());
if (f_unlink((const char *)ftp.filename) != 0){ if (f_unlink((const char *)ftpc.filename) != 0){
printf("\r\nCould not delete.\r\n"); printf("\r\nCould not delete.\r\n");
} }
else{ else{
@ -249,6 +190,7 @@ uint8_t ftpc_run(uint8_t * dbuf)
gMenuStart = 1; gMenuStart = 1;
break; break;
} }
#endif
else{ else{
printf("\r\nRetry...\r\n"); printf("\r\nRetry...\r\n");
} }
@ -262,17 +204,17 @@ uint8_t ftpc_run(uint8_t * dbuf)
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
case f_put: case f_put:
printf(">put filename?"); printf(">put file name?");
sprintf(dat,"STOR %s\r\n", User_Keyboard_MSG()); sprintf(dat,"STOR %s\r\n", User_Keyboard_MSG());
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
case f_get: case f_get:
printf(">get filename?"); printf(">get file name?");
sprintf(dat,"RETR %s\r\n", User_Keyboard_MSG()); sprintf(dat,"RETR %s\r\n", User_Keyboard_MSG());
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
default: default:
printf("shit!!!! Command.First = default\r\n"); printf("Command.First = default\r\n");
break; break;
} }
} }
@ -301,7 +243,7 @@ uint8_t ftpc_run(uint8_t * dbuf)
break; break;
case SOCK_CLOSED : case SOCK_CLOSED :
printf("%d:FTPStart\r\n",CTRL_SOCK); printf("%d:FTPStart\r\n",CTRL_SOCK);
if((ret=socket(CTRL_SOCK, Sn_MR_TCP, IPPORT_FTP, 0x0)) != CTRL_SOCK){ if((ret=socket(CTRL_SOCK, Sn_MR_TCP, FTP_destport, 0x0)) != CTRL_SOCK){
printf("%d:socket() error:%ld\r\n", CTRL_SOCK, ret); printf("%d:socket() error:%ld\r\n", CTRL_SOCK, ret);
close(CTRL_SOCK); close(CTRL_SOCK);
return ret; return ret;
@ -313,7 +255,7 @@ uint8_t ftpc_run(uint8_t * dbuf)
printf("%d:Connect error\r\n",CTRL_SOCK); printf("%d:Connect error\r\n",CTRL_SOCK);
return ret; return ret;
} }
connect_state_controlc = 0; connect_state_control_ftpc = 0;
printf("%d:Connectting...\r\n",CTRL_SOCK); printf("%d:Connectting...\r\n",CTRL_SOCK);
break; break;
default : default :
@ -322,15 +264,14 @@ uint8_t ftpc_run(uint8_t * dbuf)
switch(getSn_SR(DATA_SOCK)){ switch(getSn_SR(DATA_SOCK)){
case SOCK_ESTABLISHED : case SOCK_ESTABLISHED :
if(!connect_state_datac){ if(!connect_state_data_ftpc){
printf("%d:FTP Data socket Connected\r\n", DATA_SOCK); printf("%d:FTP Data socket Connected\r\n", DATA_SOCK);
connect_state_datac = 1; connect_state_data_ftpc = 1;
//gDataSockReady = 1;
} }
if(gDataPutGetStart){ if(gDataPutGetStart){
switch(Command.Second){ switch(Command.Second){
case s_dir: case s_dir:
printf("waitng...\r\n"); printf("dir waiting...\r\n");
if((size = getSn_RX_RSR(DATA_SOCK)) > 0){ // Don't need to check SOCKERR_BUSY because it doesn't not occur. if((size = getSn_RX_RSR(DATA_SOCK)) > 0){ // Don't need to check SOCKERR_BUSY because it doesn't not occur.
printf("ok\r\n"); printf("ok\r\n");
memset(dbuf, 0, _MAX_SS); memset(dbuf, 0, _MAX_SS);
@ -347,17 +288,19 @@ uint8_t ftpc_run(uint8_t * dbuf)
} }
printf("Rcvd Data:\n\r%s\n\r", dbuf); printf("Rcvd Data:\n\r%s\n\r", dbuf);
gDataPutGetStart = 0; gDataPutGetStart = 0;
Command.Second = s_nocmd;
} }
break; break;
case s_put: case s_put:
printf("waitng...\r\n"); printf("put waiting...\r\n");
if(strlen(ftp.workingdir) == 1) if(strlen(ftpc.workingdir) == 1)
sprintf(ftp.filename, "/%s", (uint8_t *)gMsgBuf); sprintf(ftpc.filename, "/%s", (uint8_t *)gMsgBuf);
else else
sprintf(ftp.filename, "%s/%s", ftp.workingdir, (uint8_t *)gMsgBuf); sprintf(ftpc.filename, "%s/%s", ftpc.workingdir, (uint8_t *)gMsgBuf);
ftp.fr = f_open(&(ftp.fil), (const char *)ftp.filename, FA_READ); #if defined(F_FILESYSTEM)
if(ftp.fr == FR_OK){ ftpc.fr = f_open(&(ftpc.fil), (const char *)ftpc.filename, FA_READ);
remain_filesize = ftp.fil.fsize; if(ftpc.fr == FR_OK){
remain_filesize = ftpc.fil.fsize;
printf("f_open return FR_OK\r\n"); printf("f_open return FR_OK\r\n");
do{ do{
memset(dbuf, 0, _MAX_SS); memset(dbuf, 0, _MAX_SS);
@ -365,8 +308,8 @@ uint8_t ftpc_run(uint8_t * dbuf)
send_byte = _MAX_SS; send_byte = _MAX_SS;
else else
send_byte = remain_filesize; send_byte = remain_filesize;
ftp.fr = f_read(&(ftp.fil), (void *)dbuf, send_byte , (UINT *)&blocklen); ftpc.fr = f_read(&(ftpc.fil), (void *)dbuf, send_byte , (UINT *)&blocklen);
if(ftp.fr != FR_OK){ if(ftpc.fr != FR_OK){
break; break;
} }
printf("#"); printf("#");
@ -374,25 +317,35 @@ uint8_t ftpc_run(uint8_t * dbuf)
remain_filesize -= blocklen; remain_filesize -= blocklen;
}while(remain_filesize != 0); }while(remain_filesize != 0);
printf("\r\nFile read finished\r\n"); printf("\r\nFile read finished\r\n");
ftp.fr = f_close(&(ftp.fil)); ftpc.fr = f_close(&(ftpc.fil));
gDataPutGetStart = 0;
disconnect(DATA_SOCK);
} }
else{ else{
printf("File Open Error: %d\r\n", ftp.fr); printf("File Open Error: %d\r\n", ftpc.fr);
ftp.fr = f_close(&(ftp.fil)); ftpc.fr = f_close(&(ftpc.fil));
gDataPutGetStart = 0;
disconnect(DATA_SOCK);
} }
#else
remain_filesize = strlen(ftpc.filename);
do{
memset(dbuf, 0, _MAX_SS);
blocklen = sprintf(dbuf, "%s", ftpc.filename);
printf("########## dbuf:%s\r\n", dbuf);
send(DATA_SOCK, dbuf, blocklen);
remain_filesize -= blocklen;
}while(remain_filesize != 0);
#endif
gDataPutGetStart = 0;
Command.Second = s_nocmd;
disconnect(DATA_SOCK);
break; break;
case s_get: case s_get:
printf("waitng...\r\n"); printf("get waiting...\r\n");
if(strlen(ftp.workingdir) == 1) if(strlen(ftpc.workingdir) == 1)
sprintf(ftp.filename, "/%s", (uint8_t *)gMsgBuf); sprintf(ftpc.filename, "/%s", (uint8_t *)gMsgBuf);
else else
sprintf(ftp.filename, "%s/%s", ftp.workingdir, (uint8_t *)gMsgBuf); sprintf(ftpc.filename, "%s/%s", ftpc.workingdir, (uint8_t *)gMsgBuf);
ftp.fr = f_open(&(ftp.fil), (const char *)ftp.filename, FA_CREATE_ALWAYS | FA_WRITE); #if defined(F_FILESYSTEM)
if(ftp.fr == FR_OK){ ftpc.fr = f_open(&(ftpc.fil), (const char *)ftpc.filename, FA_CREATE_ALWAYS | FA_WRITE);
if(ftpc.fr == FR_OK){
printf("f_open return FR_OK\r\n"); printf("f_open return FR_OK\r\n");
while(1){ while(1){
if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){ if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){
@ -401,15 +354,15 @@ uint8_t ftpc_run(uint8_t * dbuf)
if(remain_datasize > _MAX_SS) recv_byte = _MAX_SS; if(remain_datasize > _MAX_SS) recv_byte = _MAX_SS;
else recv_byte = remain_datasize; else recv_byte = remain_datasize;
ret = recv(DATA_SOCK, dbuf, recv_byte); ret = recv(DATA_SOCK, dbuf, recv_byte);
ftp.fr = f_write(&(ftp.fil), (const void *)dbuf, (UINT)ret, (UINT *)&blocklen); ftpc.fr = f_write(&(ftpc.fil), (const void *)dbuf, (UINT)ret, (UINT *)&blocklen);
remain_datasize -= blocklen; remain_datasize -= blocklen;
if(ftp.fr != FR_OK){ if(ftpc.fr != FR_OK){
printf("f_write failed\r\n"); printf("f_write failed\r\n");
break; break;
} }
if(remain_datasize <= 0) break; if(remain_datasize <= 0) break;
} }
if(ftp.fr != FR_OK){ if(ftpc.fr != FR_OK){
printf("f_write failed\r\n"); printf("f_write failed\r\n");
break; break;
} }
@ -420,14 +373,37 @@ uint8_t ftpc_run(uint8_t * dbuf)
} }
} }
printf("\r\nFile write finished\r\n"); printf("\r\nFile write finished\r\n");
ftp.fr = f_close(&(ftp.fil)); ftpc.fr = f_close(&(ftpc.fil));
gDataPutGetStart = 0; gDataPutGetStart = 0;
}else{ }else{
printf("File Open Error: %d\r\n", ftp.fr); printf("File Open Error: %d\r\n", ftpc.fr);
} }
#else
while(1){
if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){
while(1){
memset(dbuf, 0, _MAX_SS);
if(remain_datasize > _MAX_SS)
recv_byte = _MAX_SS;
else
recv_byte = remain_datasize;
ret = recv(DATA_SOCK, dbuf, recv_byte);
printf("########## dbuf:%s\r\n", dbuf);
remain_datasize -= ret;
if(remain_datasize <= 0)
break;
}
}else{
if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED)
break;
}
}
gDataPutGetStart = 0;
Command.Second = s_nocmd;
#endif
break; break;
default: default:
printf("shit!!!! Command.Second = default\r\n"); printf("Command.Second = default\r\n");
break; break;
} }
} }
@ -438,8 +414,8 @@ uint8_t ftpc_run(uint8_t * dbuf)
printf("%d:Closed\r\n",DATA_SOCK); printf("%d:Closed\r\n",DATA_SOCK);
break; break;
case SOCK_CLOSED : case SOCK_CLOSED :
if(ftp.dsock_state == DATASOCK_READY){ if(ftpc.dsock_state == DATASOCK_READY){
if(ftp.dsock_mode == PASSIVE_MODE){ if(ftpc.dsock_mode == PASSIVE_MODE){
printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port); printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port);
if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK){ if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK){
printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret); printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret);
@ -460,13 +436,13 @@ uint8_t ftpc_run(uint8_t * dbuf)
if(local_port > 50000) if(local_port > 50000)
local_port = 35000; local_port = 35000;
} }
ftp.dsock_state = DATASOCK_START; ftpc.dsock_state = DATASOCK_START;
} }
break; break;
case SOCK_INIT : case SOCK_INIT :
printf("%d:Opened\r\n",DATA_SOCK); printf("%d:Opened\r\n",DATA_SOCK);
if(ftp.dsock_mode == ACTIVE_MODE){ if(ftpc.dsock_mode == ACTIVE_MODE){
if( (ret = listen(DATA_SOCK)) != SOCK_OK){ if( (ret = listen(DATA_SOCK)) != SOCK_OK){
printf("%d:Listen error\r\n",DATA_SOCK); printf("%d:Listen error\r\n",DATA_SOCK);
return ret; return ret;
@ -480,11 +456,12 @@ uint8_t ftpc_run(uint8_t * dbuf)
} }
gDataSockReady = 1; gDataSockReady = 1;
} }
connect_state_datac = 0; connect_state_data_ftpc = 0;
break; break;
default : default :
break; break;
} }
#endif
return 0; return 0;
} }
@ -496,55 +473,58 @@ char proc_ftpc(char * buf)
Responses =(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0'); Responses =(buf[0]-'0')*100+(buf[1]-'0')*10+(buf[2]-'0');
switch(Responses){ switch(Responses){
case R_220: case R_220: /* Service ready for new user. */
printf("\r\nInput your User ID > "); printf("\r\nInput your User ID > ");
sprintf(dat,"USER %s\r\n", User_Keyboard_MSG()); sprintf(dat,"USER %s\r\n", User_Keyboard_MSG());
printf("\r\n"); printf("\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
case R_331:
case R_331: /* User name okay, need password. */
printf("\r\nInput your Password > "); printf("\r\nInput your Password > ");
sprintf(dat,"PASS %s\r\n", User_Keyboard_MSG()); sprintf(dat,"PASS %s\r\n", User_Keyboard_MSG());
printf("\r\n"); printf("\r\n");
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
case R_230: case R_230: /* User logged in, proceed */
printf("\r\nUser logged in, proceed\r\n"); printf("\r\nUser logged in, proceed\r\n");
sprintf(dat,"TYPE %c\r\n", TransferAscii); sprintf(dat,"TYPE %c\r\n", TransferAscii);
gModeAsciiBinary = TransferAscii; ftpc.type = ASCII_TYPE;
send(CTRL_SOCK, (uint8_t *)dat, strlen(dat)); send(CTRL_SOCK, (uint8_t *)dat, strlen(dat));
break; break;
case R_200: case R_200:
if((gModeActivePassive==ConnectActive)&&gModeActivePassiveflag){ if((ftpc.dsock_mode==ACTIVE_MODE)&&gModeActivePassiveflag){
ftp.dsock_mode = ACTIVE_MODE; ftpc.dsock_state = DATASOCK_READY;
ftp.dsock_state = DATASOCK_READY;
gModeActivePassiveflag = 0; gModeActivePassiveflag = 0;
} }
else{ else{
gMenuStart = 1; gMenuStart = 1;
} }
break; break;
case R_150: case R_150:
switch(Command.First){ switch(Command.First){
case f_dir: case f_dir:
Command.First = f_nocmd;
Command.Second = s_dir; Command.Second = s_dir;
gDataPutGetStart = 1; gDataPutGetStart = 1;
break; break;
case f_get: case f_get:
Command.First = f_nocmd;
Command.Second = s_get; Command.Second = s_get;
gDataPutGetStart = 1; gDataPutGetStart = 1;
break; break;
case f_put: case f_put:
Command.First = f_nocmd;
Command.Second = s_put; Command.Second = s_put;
gDataPutGetStart = 1; gDataPutGetStart = 1;
break; break;
default : default :
printf("shit!!!! Command.First = default\r\n"); printf("Command.First = default\r\n");
break; break;
} }
break; break;
case R_226: /* Closing data connection. File transfer/abort successful */ case R_226:
gMenuStart = 1; gMenuStart = 1;
break; break;
case R_227: case R_227:
@ -553,8 +533,8 @@ char proc_ftpc(char * buf)
} }
else{ else{
printf("Go Open Data Sock...\r\n "); printf("Go Open Data Sock...\r\n ");
ftp.dsock_mode = PASSIVE_MODE; ftpc.dsock_mode = PASSIVE_MODE;
ftp.dsock_state = DATASOCK_READY; ftpc.dsock_state = DATASOCK_READY;
} }
break; break;
default: default:
@ -592,22 +572,13 @@ int pportc(char * arg)
printf("ip : %d.%d.%d.%d, port : %d\r\n", remote_ip.cVal[0], remote_ip.cVal[1], remote_ip.cVal[2], remote_ip.cVal[3], remote_port); printf("ip : %d.%d.%d.%d, port : %d\r\n", remote_ip.cVal[0], remote_ip.cVal[1], remote_ip.cVal[2], remote_ip.cVal[3], remote_port);
return 0; return 0;
} }
uint8_t* User_Keyboard_MSG()
#if defined(F_FILESYSTEM)
void print_filedsc(FIL *fil)
{ {
#if defined(_FTP_DEBUG_) uint8_t i=0;
printf("File System pointer : %08X\r\n", fil->fs); do{
printf("File System mount ID : %d\r\n", fil->id); gMsgBuf[i] = ftp_getc();
printf("File status flag : %08X\r\n", fil->flag); i++;
printf("File System pads : %08X\r\n", fil->err); }while(gMsgBuf[i-1]!=0x0d);
printf("File read write pointer : %08X\r\n", fil->fptr); gMsgBuf[i-1]=0;
printf("File size : %08X\r\n", fil->fsize); return gMsgBuf;
printf("File start cluster : %08X\r\n", fil->sclust);
printf("current cluster : %08X\r\n", fil->clust);
printf("current data sector : %08X\r\n", fil->dsect);
printf("dir entry sector : %08X\r\n", fil->dir_sect);
printf("dir entry pointer : %08X\r\n", fil->dir_ptr);
#endif
} }
#endif

View File

@ -1,77 +1,106 @@
#ifndef _FTPC_H_ #ifndef _FTPC_H_
#define _FTPC_H_ #define _FTPC_H_
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <stdarg.h>
#include "stdio_private.h"
#include "socket.h"
#define F_FILESYSTEM // If your target support a file system, you have to activate this feature and implement. #define F_APP_FTPC
#if defined(F_FILESYSTEM) /* If your target support a file system, you have to activate this feature and implement. */
//#define F_FILESYSTEM
/* Change to your Chipset Uart function, you have to activate this feature and implement.
* Change!! -> Board_UARTGetCharBlocking()
* Below is an example of a function of lpc_chip library. */
//#define ftp_getc() Board_UARTGetCharBlocking()
#ifdef F_FILESYSTEM
#include "ff.h" #include "ff.h"
#endif #endif
#define F_APP_FTP #ifndef ftp_getc()
#define _FTP_DEBUG_ #define Need_UARTGetCharBlocking_func
#define F_APP_FTP_CLIENT #else
/* Change library
* Change!! -> board_api.h,
* Below is an example of a function of lpc_chip library. */
#include "board_api.h"
#endif
#define LINELEN 100 #define LINELEN 100
//#define DATA_BUF_SIZE 100 #ifndef F_FILESYSTEM
#if !defined(F_FILESYSTEM)
#define _MAX_SS 512 #define _MAX_SS 512
#endif #endif
#define CTRL_SOCK 2 #define CTRL_SOCK 2
#define DATA_SOCK 3 #define DATA_SOCK 3
#define IPPORT_FTPD 20 /* FTP Data port */ /* FTP Responses */
#define IPPORT_FTP 21 /* FTP Control port */ #define R_150 150 /* File status ok; opening data conn */
#define R_200 200 /* 'Generic' command ok */
#define R_220 220 /* Service ready for new user. */
#define R_226 226 /* Closing data connection. File transfer/abort successful */
#define R_227 227 /* Entering passive mode (h1,h2,h3,h4,p1,p2) */
#define R_230 230 /* User logged in, proceed */
#define R_331 331 /* User name okay, need password. */
#define HOSTNAME "iinChip" #define TransferAscii 'A'
#define VERSION "1.0" #define TransferBinary 'I'
#define FILENAME "a.txt" enum ftpc_type {
enum ftp_type {
ASCII_TYPE, ASCII_TYPE,
IMAGE_TYPE, IMAGE_TYPE,
LOGICAL_TYPE
}; };
enum ftp_state { enum ftpc_datasock_state{
FTPS_NOT_LOGIN,
FTPS_LOGIN
};
enum datasock_state{
DATASOCK_IDLE, DATASOCK_IDLE,
DATASOCK_READY, DATASOCK_READY,
DATASOCK_START DATASOCK_START
}; };
enum datasock_mode{ enum ftpc_datasock_mode{
PASSIVE_MODE, PASSIVE_MODE,
ACTIVE_MODE ACTIVE_MODE
}; };
enum CommandFirst {
struct ftpd { f_nocmd,
f_dir,
f_put,
f_get,
};
enum CommandSecond {
s_nocmd,
s_dir,
s_put,
s_get,
};
struct Command {
enum CommandFirst First;
enum CommandSecond Second;
};
struct ftpc {
uint8_t control; /* Control stream */ uint8_t control; /* Control stream */
uint8_t data; /* Data stream */ uint8_t data; /* Data stream */
enum ftp_type type; /* Transfer type */ enum ftpc_type type; /* Transfer type */
enum ftp_state state;
enum datasock_state dsock_state; enum ftpc_datasock_state dsock_state;
enum datasock_mode dsock_mode; enum ftpc_datasock_mode dsock_mode;
char username[LINELEN]; /* Arg to USER command */
char workingdir[LINELEN]; char workingdir[LINELEN];
char filename[LINELEN]; char filename[LINELEN];
#if defined(F_FILESYSTEM) #ifdef F_FILESYSTEM
FIL fil; // FatFs File objects FIL fil; // FatFs File objects
FRESULT fr; // FatFs function common result code FRESULT fr; // FatFs function common result code
#endif #endif
}; };
#ifndef un_I2cval #ifndef un_I2cval
@ -87,13 +116,4 @@ char proc_ftpc(char * buf);
int pportc(char * arg); int pportc(char * arg);
uint8_t* User_Keyboard_MSG(); uint8_t* User_Keyboard_MSG();
int sendit(char * command);
int recvit(char * command);
long sendfile(uint8_t s, char * command);
long recvfile(uint8_t s);
#if defined(F_FILESYSTEM)
void print_filedsc(FIL *fil);
#endif
#endif // _FTPC_H_ #endif // _FTPC_H_

583
Internet/MQTT/MQTTClient.c Normal file
View File

@ -0,0 +1,583 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTClient.h"
static void NewMessageData(MessageData* md, MQTTString* aTopicName, MQTTMessage* aMessage) {
md->topicName = aTopicName;
md->message = aMessage;
}
static int getNextPacketId(MQTTClient *c) {
return c->next_packetid = (c->next_packetid == MAX_PACKET_ID) ? 1 : c->next_packetid + 1;
}
static int sendPacket(MQTTClient* c, int length, Timer* timer)
{
int rc = FAILURE,
sent = 0;
while (sent < length && !TimerIsExpired(timer))
{
rc = c->ipstack->mqttwrite(c->ipstack, &c->buf[sent], length, TimerLeftMS(timer));
if (rc < 0) // there was an error writing the data
break;
sent += rc;
}
if (sent == length)
{
TimerCountdown(&c->ping_timer, c->keepAliveInterval); // record the fact that we have successfully sent the packet
rc = SUCCESSS;
}
else
rc = FAILURE;
return rc;
}
void MQTTClientInit(MQTTClient* c, Network* network, unsigned int command_timeout_ms,
unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size)
{
int i;
c->ipstack = network;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
c->messageHandlers[i].topicFilter = 0;
c->command_timeout_ms = command_timeout_ms;
c->buf = sendbuf;
c->buf_size = sendbuf_size;
c->readbuf = readbuf;
c->readbuf_size = readbuf_size;
c->isconnected = 0;
c->ping_outstanding = 0;
c->defaultMessageHandler = NULL;
c->next_packetid = 1;
TimerInit(&c->ping_timer);
#if defined(MQTT_TASK)
MutexInit(&c->mutex);
#endif
}
static int decodePacket(MQTTClient* c, int* value, int timeout)
{
unsigned char i;
int multiplier = 1;
int len = 0;
const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
*value = 0;
do
{
int rc = MQTTPACKET_READ_ERROR;
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
{
rc = MQTTPACKET_READ_ERROR; /* bad data */
goto exit;
}
rc = c->ipstack->mqttread(c->ipstack, &i, 1, timeout);
if (rc != 1)
goto exit;
*value += (i & 127) * multiplier;
multiplier *= 128;
} while ((i & 128) != 0);
exit:
return len;
}
static int readPacket(MQTTClient* c, Timer* timer)
{
int rc = FAILURE;
MQTTHeader header = {0};
int len = 0;
int rem_len = 0;
/* 1. read the header byte. This has the packet type in it */
if (c->ipstack->mqttread(c->ipstack, c->readbuf, 1, TimerLeftMS(timer)) != 1)
goto exit;
len = 1;
/* 2. read the remaining length. This is variable in itself */
decodePacket(c, &rem_len, TimerLeftMS(timer));
len += MQTTPacket_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
if (rem_len > 0 && (c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, TimerLeftMS(timer)) != rem_len))
goto exit;
header.byte = c->readbuf[0];
rc = header.bits.type;
exit:
return rc;
}
// assume topic filter and name is in correct format
// # can only be at end
// + and # can only be next to separator
static char isTopicMatched(char* topicFilter, MQTTString* topicName)
{
char* curf = topicFilter;
char* curn = topicName->lenstring.data;
char* curn_end = curn + topicName->lenstring.len;
while (*curf && curn < curn_end)
{
if (*curn == '/' && *curf != '/')
break;
if (*curf != '+' && *curf != '#' && *curf != *curn)
break;
if (*curf == '+')
{ // skip until we meet the next separator, or end of string
char* nextpos = curn + 1;
while (nextpos < curn_end && *nextpos != '/')
nextpos = ++curn + 1;
}
else if (*curf == '#')
curn = curn_end - 1; // skip until end of string
curf++;
curn++;
};
return (curn == curn_end) && (*curf == '\0');
}
int deliverMessage(MQTTClient* c, MQTTString* topicName, MQTTMessage* message)
{
int i;
int rc = FAILURE;
// we have to find the right message handler - indexed by topic
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) ||
isTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName)))
{
if (c->messageHandlers[i].fp != NULL)
{
MessageData md;
NewMessageData(&md, topicName, message);
c->messageHandlers[i].fp(&md);
rc = SUCCESSS;
}
}
}
if (rc == FAILURE && c->defaultMessageHandler != NULL)
{
MessageData md;
NewMessageData(&md, topicName, message);
c->defaultMessageHandler(&md);
rc = SUCCESSS;
}
return rc;
}
int keepalive(MQTTClient* c)
{
int rc = FAILURE;
if (c->keepAliveInterval == 0)
{
rc = SUCCESSS;
goto exit;
}
if (TimerIsExpired(&c->ping_timer))
{
if (!c->ping_outstanding)
{
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, 1000);
int len = MQTTSerialize_pingreq(c->buf, c->buf_size);
if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESSS) // send the ping packet
c->ping_outstanding = 1;
}
}
exit:
return rc;
}
int cycle(MQTTClient* c, Timer* timer)
{
// read the socket, see what work is due
unsigned short packet_type = readPacket(c, timer);
int len = 0,
rc = SUCCESSS;
switch (packet_type)
{
case CONNACK:
case PUBACK:
case SUBACK:
break;
case PUBLISH:
{
MQTTString topicName;
MQTTMessage msg;
int intQoS;
if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
(unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
goto exit;
msg.qos = (enum QoS)intQoS;
deliverMessage(c, &topicName, &msg);
if (msg.qos != QOS0)
{
if (msg.qos == QOS1)
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
else if (msg.qos == QOS2)
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
if (len <= 0)
rc = FAILURE;
else
rc = sendPacket(c, len, timer);
if (rc == FAILURE)
goto exit; // there was a problem
}
break;
}
case PUBREC:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
rc = FAILURE;
else if ((rc = sendPacket(c, len, timer)) != SUCCESSS) // send the PUBREL packet
rc = FAILURE; // there was a problem
if (rc == FAILURE)
goto exit; // there was a problem
break;
}
case PUBCOMP:
break;
case PINGRESP:
c->ping_outstanding = 0;
break;
}
keepalive(c);
exit:
if (rc == SUCCESSS)
rc = packet_type;
return rc;
}
int MQTTYield(MQTTClient* c, int timeout_ms)
{
int rc = SUCCESSS;
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, timeout_ms);
do
{
if (cycle(c, &timer) == FAILURE)
{
rc = FAILURE;
break;
}
} while (!TimerIsExpired(&timer));
return rc;
}
void MQTTRun(void* parm)
{
Timer timer;
MQTTClient* c = (MQTTClient*)parm;
TimerInit(&timer);
while (1)
{
#if defined(MQTT_TASK)
MutexLock(&c->mutex);
#endif
TimerCountdownMS(&timer, 500); /* Don't wait too long if no traffic is incoming */
cycle(c, &timer);
#if defined(MQTT_TASK)
MutexUnlock(&c->mutex);
#endif
}
}
#if defined(MQTT_TASK)
int MQTTStartTask(MQTTClient* client)
{
return ThreadStart(&client->thread, &MQTTRun, client);
}
#endif
int waitfor(MQTTClient* c, int packet_type, Timer* timer)
{
int rc = FAILURE;
do
{
if (TimerIsExpired(timer))
break; // we timed out
}
while ((rc = cycle(c, timer)) != packet_type);
return rc;
}
int MQTTConnect(MQTTClient* c, MQTTPacket_connectData* options)
{
Timer connect_timer;
int rc = FAILURE;
MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
int len = 0;
#if defined(MQTT_TASK)
MutexLock(&c->mutex);
#endif
if (c->isconnected) /* don't send connect packet again if we are already connected */
goto exit;
TimerInit(&connect_timer);
TimerCountdownMS(&connect_timer, c->command_timeout_ms);
if (options == 0)
options = &default_options; /* set default options if none were supplied */
c->keepAliveInterval = options->keepAliveInterval;
TimerCountdown(&c->ping_timer, c->keepAliveInterval);
if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0)
goto exit;
if ((rc = sendPacket(c, len, &connect_timer)) != SUCCESSS) // send the connect packet
goto exit; // there was a problem
// this will be a blocking call, wait for the connack
if (waitfor(c, CONNACK, &connect_timer) == CONNACK)
{
unsigned char connack_rc = 255;
unsigned char sessionPresent = 0;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1)
rc = connack_rc;
else
rc = FAILURE;
}
else
rc = FAILURE;
exit:
if (rc == SUCCESSS)
c->isconnected = 1;
#if defined(MQTT_TASK)
MutexUnlock(&c->mutex);
#endif
return rc;
}
int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos, messageHandler messageHandler)
{
int rc = FAILURE;
Timer timer;
int len = 0;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicFilter;
#if defined(MQTT_TASK)
MutexLock(&c->mutex);
#endif
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&qos);
if (len <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESSS) // send the subscribe packet
goto exit; // there was a problem
if (waitfor(c, SUBACK, &timer) == SUBACK) // wait for suback
{
int count = 0, grantedQoS = -1;
unsigned short mypacketid;
if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1)
rc = grantedQoS; // 0, 1, 2 or 0x80
if (rc != 0x80)
{
int i;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == 0)
{
c->messageHandlers[i].topicFilter = topicFilter;
c->messageHandlers[i].fp = messageHandler;
rc = 0;
break;
}
}
}
}
else
rc = FAILURE;
exit:
#if defined(MQTT_TASK)
MutexUnlock(&c->mutex);
#endif
return rc;
}
int MQTTUnsubscribe(MQTTClient* c, const char* topicFilter)
{
int rc = FAILURE;
Timer timer;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicFilter;
int len = 0;
#if defined(MQTT_TASK)
MutexLock(&c->mutex);
#endif
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESSS) // send the subscribe packet
goto exit; // there was a problem
if (waitfor(c, UNSUBACK, &timer) == UNSUBACK)
{
unsigned short mypacketid; // should be the same as the packetid above
if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1)
rc = 0;
}
else
rc = FAILURE;
exit:
#if defined(MQTT_TASK)
MutexUnlock(&c->mutex);
#endif
return rc;
}
int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message)
{
int rc = FAILURE;
Timer timer;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicName;
int len = 0;
#if defined(MQTT_TASK)
MutexLock(&c->mutex);
#endif
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
if (message->qos == QOS1 || message->qos == QOS2)
message->id = getNextPacketId(c);
len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id,
topic, (unsigned char*)message->payload, message->payloadlen);
if (len <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESSS) // send the subscribe packet
goto exit; // there was a problem
if (message->qos == QOS1)
{
if (waitfor(c, PUBACK, &timer) == PUBACK)
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
}
else
rc = FAILURE;
}
else if (message->qos == QOS2)
{
if (waitfor(c, PUBCOMP, &timer) == PUBCOMP)
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
}
else
rc = FAILURE;
}
exit:
#if defined(MQTT_TASK)
MutexUnlock(&c->mutex);
#endif
return rc;
}
int MQTTDisconnect(MQTTClient* c)
{
int rc = FAILURE;
Timer timer; // we might wait for incomplete incoming publishes to complete
int len = 0;
#if defined(MQTT_TASK)
MutexLock(&c->mutex);
#endif
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
len = MQTTSerialize_disconnect(c->buf, c->buf_size);
if (len > 0)
rc = sendPacket(c, len, &timer); // send the disconnect packet
c->isconnected = 0;
#if defined(MQTT_TASK)
MutexUnlock(&c->mutex);
#endif
return rc;
}

182
Internet/MQTT/MQTTClient.h Normal file
View File

@ -0,0 +1,182 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - documentation and platform specific header
*******************************************************************************/
#if !defined(__MQTT_CLIENT_C_)
#define __MQTT_CLIENT_C_
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(WIN32_DLL) || defined(WIN64_DLL)
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
#elif defined(LINUX_SO)
#define DLLImport extern
#define DLLExport __attribute__ ((visibility ("default")))
#else
#define DLLImport
#define DLLExport
#endif
#include "./MQTTPacket/src/MQTTPacket.h"
#include "stdio.h"
#include "mqtt_interface.h"
#define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */
#if !defined(MAX_MESSAGE_HANDLERS)
#define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */
#endif
enum QoS { QOS0, QOS1, QOS2 };
/* all failure return codes must be negative */
enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1, SUCCESSS = 0 };
/* The Platform specific header must define the Network and Timer structures and functions
* which operate on them.
*
typedef struct Network
{
int (*mqttread)(Network*, unsigned char* read_buffer, int, int);
int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int);
} Network;*/
/* The Timer structure must be defined in the platform specific header,
* and have the following functions to operate on it. */
extern void TimerInit(Timer*);
extern char TimerIsExpired(Timer*);
extern void TimerCountdownMS(Timer*, unsigned int);
extern void TimerCountdown(Timer*, unsigned int);
extern int TimerLeftMS(Timer*);
typedef struct MQTTMessage
{
enum QoS qos;
unsigned char retained;
unsigned char dup;
unsigned short id;
void *payload;
size_t payloadlen;
} MQTTMessage;
typedef struct MessageData
{
MQTTMessage* message;
MQTTString* topicName;
} MessageData;
typedef void (*messageHandler)(MessageData*);
typedef struct MQTTClient
{
unsigned int next_packetid,
command_timeout_ms;
size_t buf_size,
readbuf_size;
unsigned char *buf,
*readbuf;
unsigned int keepAliveInterval;
char ping_outstanding;
int isconnected;
struct MessageHandlers
{
const char* topicFilter;
void (*fp) (MessageData*);
} messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */
void (*defaultMessageHandler) (MessageData*);
Network* ipstack;
Timer ping_timer;
#if defined(MQTT_TASK)
Mutex mutex;
Thread thread;
#endif
} MQTTClient;
#define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0}
/**
* Create an MQTT client object
* @param client
* @param network
* @param command_timeout_ms
* @param
*/
DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms,
unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size);
/** MQTT Connect - send an MQTT connect packet down the network and wait for a Connack
* The nework object must be connected to the network endpoint before calling this
* @param options - connect options
* @return success code
*/
DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options);
/** MQTT Publish - send an MQTT publish packet and wait for all acks to complete for all QoSs
* @param client - the client object to use
* @param topic - the topic to publish to
* @param message - the message to send
* @return success code
*/
DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*);
/** MQTT Subscribe - send an MQTT subscribe packet and wait for suback before returning.
* @param client - the client object to use
* @param topicFilter - the topic filter to subscribe to
* @param message - the message to send
* @return success code
*/
DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler);
/** MQTT Subscribe - send an MQTT unsubscribe packet and wait for unsuback before returning.
* @param client - the client object to use
* @param topicFilter - the topic filter to unsubscribe from
* @return success code
*/
DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter);
/** MQTT Disconnect - send an MQTT disconnect packet and close the connection
* @param client - the client object to use
* @return success code
*/
DLLExport int MQTTDisconnect(MQTTClient* client);
/** MQTT Yield - MQTT background
* @param client - the client object to use
* @param time - the time, in milliseconds, to yield for
* @return success code
*/
DLLExport int MQTTYield(MQTTClient* client, int time);
#if defined(MQTT_TASK)
/** MQTT start background thread for a client. After this, MQTTYield should not be called.
* @param client - the client object to use
* @return success code
*/
DLLExport int MQTTStartTask(MQTTClient* client);
#endif
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,136 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTCONNECT_H_
#define MQTTCONNECT_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
typedef union
{
unsigned char all; /**< all connect flags */
#if defined(REVERSED)
struct
{
unsigned int username : 1; /**< 3.1 user name */
unsigned int password : 1; /**< 3.1 password */
unsigned int willRetain : 1; /**< will retain setting */
unsigned int willQoS : 2; /**< will QoS value */
unsigned int will : 1; /**< will flag */
unsigned int cleansession : 1; /**< clean session flag */
unsigned int : 1; /**< unused */
} bits;
#else
struct
{
unsigned int : 1; /**< unused */
unsigned int cleansession : 1; /**< cleansession flag */
unsigned int will : 1; /**< will flag */
unsigned int willQoS : 2; /**< will QoS value */
unsigned int willRetain : 1; /**< will retain setting */
unsigned int password : 1; /**< 3.1 password */
unsigned int username : 1; /**< 3.1 user name */
} bits;
#endif
} MQTTConnectFlags; /**< connect flags byte */
/**
* Defines the MQTT "Last Will and Testament" (LWT) settings for
* the connect packet.
*/
typedef struct
{
/** The eyecatcher for this structure. must be MQTW. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** The LWT topic to which the LWT message will be published. */
MQTTString topicName;
/** The LWT payload. */
MQTTString message;
/**
* The retained flag for the LWT message (see MQTTAsync_message.retained).
*/
unsigned char retained;
/**
* The quality of service setting for the LWT message (see
* MQTTAsync_message.qos and @ref qos).
*/
char qos;
} MQTTPacket_willOptions;
#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 }
typedef struct
{
/** The eyecatcher for this structure. must be MQTC. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1
*/
unsigned char MQTTVersion;
MQTTString clientID;
unsigned short keepAliveInterval;
unsigned char cleansession;
unsigned char willFlag;
MQTTPacket_willOptions will;
MQTTString username;
MQTTString password;
} MQTTPacket_connectData;
typedef union
{
unsigned char all; /**< all connack flags */
#if defined(REVERSED)
struct
{
unsigned int sessionpresent : 1; /**< session present flag */
unsigned int : 7; /**< unused */
} bits;
#else
struct
{
unsigned int : 7; /**< unused */
unsigned int sessionpresent : 1; /**< session present flag */
} bits;
#endif
} MQTTConnackFlags; /**< connack flags byte */
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options);
DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len);
DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent);
DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen);
DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen);
DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen);
#endif /* MQTTCONNECT_H_ */

View File

@ -0,0 +1,214 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT connect packet that would be produced using the supplied connect options.
* @param options the options to be used to build the connect packet
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_connectLength(MQTTPacket_connectData* options)
{
int len = 0;
FUNC_ENTRY;
if (options->MQTTVersion == 3)
len = 12; /* variable depending on MQTT or MQIsdp */
else if (options->MQTTVersion == 4)
len = 10;
len += MQTTstrlen(options->clientID)+2;
if (options->willFlag)
len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2;
if (options->username.cstring || options->username.lenstring.data)
len += MQTTstrlen(options->username)+2;
if (options->password.cstring || options->password.lenstring.data)
len += MQTTstrlen(options->password)+2;
FUNC_EXIT_RC(len);
return len;
}
/**
* Serializes the connect options into the buffer.
* @param buf the buffer into which the packet will be serialized
* @param len the length in bytes of the supplied buffer
* @param options the options to be used to build the connect packet
* @return serialized length, or error if 0
*/
int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options)
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
MQTTConnectFlags flags = {0};
int len = 0;
int rc = -1;
FUNC_ENTRY;
if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = CONNECT;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, len); /* write remaining length */
if (options->MQTTVersion == 4)
{
writeCString(&ptr, "MQTT");
writeChar(&ptr, (char) 4);
}
else
{
writeCString(&ptr, "MQIsdp");
writeChar(&ptr, (char) 3);
}
flags.all = 0;
flags.bits.cleansession = options->cleansession;
flags.bits.will = (options->willFlag) ? 1 : 0;
if (flags.bits.will)
{
flags.bits.willQoS = options->will.qos;
flags.bits.willRetain = options->will.retained;
}
if (options->username.cstring || options->username.lenstring.data)
flags.bits.username = 1;
if (options->password.cstring || options->password.lenstring.data)
flags.bits.password = 1;
writeChar(&ptr, flags.all);
writeInt(&ptr, options->keepAliveInterval);
writeMQTTString(&ptr, options->clientID);
if (options->willFlag)
{
writeMQTTString(&ptr, options->will.topicName);
writeMQTTString(&ptr, options->will.message);
}
if (flags.bits.username)
writeMQTTString(&ptr, options->username);
if (flags.bits.password)
writeMQTTString(&ptr, options->password);
rc = ptr - buf;
exit: FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into connack data - return code
* @param sessionPresent the session present flag returned (only for MQTT 3.1.1)
* @param connack_rc returned integer value of the connack return code
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param len the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
MQTTConnackFlags flags = {0};
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != CONNACK)
goto exit;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
flags.all = readChar(&curdata);
*sessionPresent = flags.bits.sessionpresent;
*connack_rc = readChar(&curdata);
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a 0-length packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @param packettype the message type
* @return serialized length, or error if 0
*/
int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype)
{
MQTTHeader header = {0};
int rc = -1;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = packettype;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @return serialized length, or error if 0
*/
int MQTTSerialize_disconnect(unsigned char* buf, int buflen)
{
return MQTTSerialize_zero(buf, buflen, DISCONNECT);
}
/**
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @return serialized length, or error if 0
*/
int MQTTSerialize_pingreq(unsigned char* buf, int buflen)
{
return MQTTSerialize_zero(buf, buflen, PINGREQ);
}

View File

@ -0,0 +1,148 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
#define min(a, b) ((a < b) ? a : b)
/**
* Validates MQTT protocol name and version combinations
* @param protocol the MQTT protocol name as an MQTTString
* @param version the MQTT protocol version number, as in the connect packet
* @return correct MQTT combination? 1 is true, 0 is false
*/
int MQTTPacket_checkVersion(MQTTString* protocol, int version)
{
int rc = 0;
if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp",
min(6, protocol->lenstring.len)) == 0)
rc = 1;
else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT",
min(4, protocol->lenstring.len)) == 0)
rc = 1;
return rc;
}
/**
* Deserializes the supplied (wire) buffer into connect data structure
* @param data the connect data structure to be filled out
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param len the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len)
{
MQTTHeader header = {0};
MQTTConnectFlags flags = {0};
unsigned char* curdata = buf;
unsigned char* enddata = &buf[len];
int rc = 0;
MQTTString Protocol;
int version;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != CONNECT)
goto exit;
curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */
if (!readMQTTLenString(&Protocol, &curdata, enddata) ||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
goto exit;
version = (int)readChar(&curdata); /* Protocol version */
/* If we don't recognize the protocol version, we don't parse the connect packet on the
* basis that we don't know what the format will be.
*/
if (MQTTPacket_checkVersion(&Protocol, version))
{
flags.all = readChar(&curdata);
data->cleansession = flags.bits.cleansession;
data->keepAliveInterval = readInt(&curdata);
if (!readMQTTLenString(&data->clientID, &curdata, enddata))
goto exit;
data->willFlag = flags.bits.will;
if (flags.bits.will)
{
data->will.qos = flags.bits.willQoS;
data->will.retained = flags.bits.willRetain;
if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) ||
!readMQTTLenString(&data->will.message, &curdata, enddata))
goto exit;
}
if (flags.bits.username)
{
if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata))
goto exit; /* username flag set, but no username supplied - invalid */
if (flags.bits.password &&
(enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata)))
goto exit; /* password flag set, but no password supplied - invalid */
}
else if (flags.bits.password)
goto exit; /* password flag set without username - invalid */
rc = 1;
}
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the connack packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param connack_rc the integer connack return code to be used
* @param sessionPresent the MQTT 3.1.1 sessionPresent flag
* @return serialized length, or error if 0
*/
int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
MQTTConnackFlags flags = {0};
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = CONNACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
flags.all = 0;
flags.bits.sessionpresent = sessionPresent;
writeChar(&ptr, flags.all);
writeChar(&ptr, connack_rc);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@ -0,0 +1,107 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
#define min(a, b) ((a < b) ? 1 : 0)
/**
* Deserializes the supplied (wire) buffer into publish data
* @param dup returned integer - the MQTT dup flag
* @param qos returned integer - the MQTT QoS value
* @param retained returned integer - the MQTT retained flag
* @param packetid returned integer - the MQTT packet identifier
* @param topicName returned MQTTString - the MQTT topic in the publish
* @param payload returned byte buffer - the MQTT publish payload
* @param payloadlen returned integer - the length of the MQTT payload
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success
*/
int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != PUBLISH)
goto exit;
*dup = header.bits.dup;
*qos = header.bits.qos;
*retained = header.bits.retain;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (!readMQTTLenString(topicName, &curdata, enddata) ||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
goto exit;
if (*qos > 0)
*packetid = readInt(&curdata);
*payloadlen = enddata - curdata;
*payload = curdata;
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into an ack
* @param packettype returned integer - the MQTT packet type
* @param dup returned integer - the MQTT dup flag
* @param packetid returned integer - the MQTT packet identifier
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
FUNC_ENTRY;
header.byte = readChar(&curdata);
*dup = header.bits.dup;
*packettype = header.bits.type;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
*packetid = readInt(&curdata);
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@ -0,0 +1,258 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
const char* MQTTPacket_names[] =
{
"RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
"PINGREQ", "PINGRESP", "DISCONNECT"
};
const char* MQTTPacket_getName(unsigned short packetid)
{
return MQTTPacket_names[packetid];
}
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)
{
int strindex = 0;
strindex = snprintf(strbuf, strbuflen,
"CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
(int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
(int)data->cleansession, data->keepAliveInterval);
if (data->willFlag)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
data->will.qos, data->will.retained,
data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
data->will.message.lenstring.len, data->will.message.lenstring.data);
if (data->username.lenstring.data && data->username.lenstring.len > 0)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
if (data->password.lenstring.data && data->password.lenstring.len > 0)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
return strindex;
}
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)
{
int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
return strindex;
}
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)
{
int strindex = snprintf(strbuf, strbuflen,
"PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
dup, qos, retained, packetid,
(topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
return strindex;
}
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
{
int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
if (dup)
strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
return strindex;
}
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[])
{
return snprintf(strbuf, strbuflen,
"SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
dup, packetid, count,
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
requestedQoSs[0]);
}
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)
{
return snprintf(strbuf, strbuflen,
"SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
}
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[])
{
return snprintf(strbuf, strbuflen,
"UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
dup, packetid, count,
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
}
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
int index = 0;
int rem_length = 0;
MQTTHeader header = {0};
int strindex = 0;
header.byte = buf[index++];
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
switch (header.bits.type)
{
case CONNACK:
{
unsigned char sessionPresent, connack_rc;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
}
break;
case PUBLISH:
{
unsigned char dup, retained, *payload;
unsigned short packetid;
int qos, payloadlen;
MQTTString topicName = MQTTString_initializer;
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
&payload, &payloadlen, buf, buflen) == 1)
strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
topicName, payload, payloadlen);
}
break;
case PUBACK:
case PUBREC:
case PUBREL:
case PUBCOMP:
{
unsigned char packettype, dup;
unsigned short packetid;
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
}
break;
case SUBACK:
{
unsigned short packetid;
int maxcount = 1, count = 0;
int grantedQoSs[1];
if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
}
break;
case UNSUBACK:
{
unsigned short packetid;
if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
}
break;
case PINGREQ:
case PINGRESP:
case DISCONNECT:
strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
break;
}
return strbuf;
}
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
int index = 0;
int rem_length = 0;
MQTTHeader header = {0};
int strindex = 0;
header.byte = buf[index++];
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
switch (header.bits.type)
{
case CONNECT:
{
MQTTPacket_connectData data;
int rc;
if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)
strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);
}
break;
case PUBLISH:
{
unsigned char dup, retained, *payload;
unsigned short packetid;
int qos, payloadlen;
MQTTString topicName = MQTTString_initializer;
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
&payload, &payloadlen, buf, buflen) == 1)
strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
topicName, payload, payloadlen);
}
break;
case PUBACK:
case PUBREC:
case PUBREL:
case PUBCOMP:
{
unsigned char packettype, dup;
unsigned short packetid;
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
}
break;
case SUBSCRIBE:
{
unsigned char dup;
unsigned short packetid;
int maxcount = 1, count = 0;
MQTTString topicFilters[1];
int requestedQoSs[1];
if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
topicFilters, requestedQoSs, buf, buflen) == 1)
strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
}
break;
case UNSUBSCRIBE:
{
unsigned char dup;
unsigned short packetid;
int maxcount = 1, count = 0;
MQTTString topicFilters[1];
if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
strindex = MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
}
break;
case PINGREQ:
case PINGRESP:
case DISCONNECT:
strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
break;
}
strbuf[strbuflen] = '\0';
return strbuf;
}

View File

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTFORMAT_H)
#define MQTTFORMAT_H
#include "StackTrace.h"
#include "MQTTPacket.h"
const char* MQTTPacket_getName(unsigned short packetid);
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data);
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent);
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen);
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid);
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[]);
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs);
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[]);
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
#endif

View File

@ -0,0 +1,410 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Sergio R. Caprile - non-blocking packet read functions for stream transport
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
/**
* Encodes the message length according to the MQTT algorithm
* @param buf the buffer into which the encoded data is written
* @param length the length to be encoded
* @return the number of bytes written to buffer
*/
int MQTTPacket_encode(unsigned char* buf, int length)
{
int rc = 0;
FUNC_ENTRY;
do
{
char d = length % 128;
length /= 128;
/* if there are more digits to encode, set the top bit of this digit */
if (length > 0)
d |= 0x80;
buf[rc++] = d;
} while (length > 0);
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Decodes the message length according to the MQTT algorithm
* @param getcharfn pointer to function to read the next character from the data source
* @param value the decoded length returned
* @return the number of bytes read from the socket
*/
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value)
{
unsigned char c;
int multiplier = 1;
int len = 0;
#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
FUNC_ENTRY;
*value = 0;
do
{
int rc = MQTTPACKET_READ_ERROR;
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
{
rc = MQTTPACKET_READ_ERROR; /* bad data */
goto exit;
}
rc = (*getcharfn)(&c, 1);
if (rc != 1)
goto exit;
*value += (c & 127) * multiplier;
multiplier *= 128;
} while ((c & 128) != 0);
exit:
FUNC_EXIT_RC(len);
return len;
}
int MQTTPacket_len(int rem_len)
{
rem_len += 1; /* header byte */
/* now remaining_length field */
if (rem_len < 128)
rem_len += 1;
else if (rem_len < 16384)
rem_len += 2;
else if (rem_len < 2097151)
rem_len += 3;
else
rem_len += 4;
return rem_len;
}
static unsigned char* bufptr;
int bufchar(unsigned char* c, int count)
{
int i;
for (i = 0; i < count; ++i)
*c = *bufptr++;
return count;
}
int MQTTPacket_decodeBuf(unsigned char* buf, int* value)
{
bufptr = buf;
return MQTTPacket_decode(bufchar, value);
}
/**
* Calculates an integer from two bytes read from the input buffer
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
* @return the integer value calculated
*/
int readInt(unsigned char** pptr)
{
unsigned char* ptr = *pptr;
int len = 256*(*ptr) + (*(ptr+1));
*pptr += 2;
return len;
}
/**
* Reads one character from the input buffer.
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
* @return the character read
*/
char readChar(unsigned char** pptr)
{
char c = **pptr;
(*pptr)++;
return c;
}
/**
* Writes one character to an output buffer.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param c the character to write
*/
void writeChar(unsigned char** pptr, char c)
{
**pptr = c;
(*pptr)++;
}
/**
* Writes an integer as 2 bytes to an output buffer.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param anInt the integer to write
*/
void writeInt(unsigned char** pptr, int anInt)
{
**pptr = (unsigned char)(anInt / 256);
(*pptr)++;
**pptr = (unsigned char)(anInt % 256);
(*pptr)++;
}
/**
* Writes a "UTF" string to an output buffer. Converts C string to length-delimited.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param string the C string to write
*/
void writeCString(unsigned char** pptr, const char* string)
{
int len = strlen(string);
writeInt(pptr, len);
memcpy(*pptr, string, len);
*pptr += len;
}
int getLenStringLen(char* ptr)
{
int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
return len;
}
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring)
{
if (mqttstring.lenstring.len > 0)
{
writeInt(pptr, mqttstring.lenstring.len);
memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);
*pptr += mqttstring.lenstring.len;
}
else if (mqttstring.cstring)
writeCString(pptr, mqttstring.cstring);
else
writeInt(pptr, 0);
}
/**
* @param mqttstring the MQTTString structure into which the data is to be read
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param enddata pointer to the end of the data: do not read beyond
* @return 1 if successful, 0 if not
*/
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata)
{
int rc = 0;
FUNC_ENTRY;
/* the first two bytes are the length of the string */
if (enddata - (*pptr) > 1) /* enough length to read the integer? */
{
mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */
if (&(*pptr)[mqttstring->lenstring.len] <= enddata)
{
mqttstring->lenstring.data = (char*)*pptr;
*pptr += mqttstring->lenstring.len;
rc = 1;
}
}
mqttstring->cstring = NULL;
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string
* @param mqttstring the string to return the length of
* @return the length of the string
*/
int MQTTstrlen(MQTTString mqttstring)
{
int rc = 0;
if (mqttstring.cstring)
rc = strlen(mqttstring.cstring);
else
rc = mqttstring.lenstring.len;
return rc;
}
/**
* Compares an MQTTString to a C string
* @param a the MQTTString to compare
* @param bptr the C string to compare
* @return boolean - equal or not
*/
int MQTTPacket_equals(MQTTString* a, char* bptr)
{
int alen = 0,
blen = 0;
char *aptr;
if (a->cstring)
{
aptr = a->cstring;
alen = strlen(a->cstring);
}
else
{
aptr = a->lenstring.data;
alen = a->lenstring.len;
}
blen = strlen(bptr);
return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);
}
/**
* Helper function to read packet data from some source into a buffer
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param getfn pointer to a function which will read any number of bytes from the needed source
* @return integer MQTT packet type, or -1 on error
* @note the whole message must fit into the caller's buffer
*/
int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int))
{
int rc = -1;
MQTTHeader header = {0};
int len = 0;
int rem_len = 0;
/* 1. read the header byte. This has the packet type in it */
if ((*getfn)(buf, 1) != 1)
goto exit;
len = 1;
/* 2. read the remaining length. This is variable in itself */
MQTTPacket_decode(getfn, &rem_len);
len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
if((rem_len + len) > buflen)
goto exit;
if ((*getfn)(buf + len, rem_len) != rem_len)
goto exit;
header.byte = buf[0];
rc = header.bits.type;
exit:
return rc;
}
/**
* Decodes the message length according to the MQTT algorithm, non-blocking
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
* @param value the decoded length returned
* @return integer the number of bytes read from the socket, 0 for call again, or -1 on error
*/
static int MQTTPacket_decodenb(MQTTTransport *trp)
{
unsigned char c;
int rc = MQTTPACKET_READ_ERROR;
FUNC_ENTRY;
if(trp->len == 0){ /* initialize on first call */
trp->multiplier = 1;
trp->rem_len = 0;
}
do {
int frc;
if (++(trp->len) > MAX_NO_OF_REMAINING_LENGTH_BYTES)
goto exit;
if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)
goto exit;
if (frc == 0){
rc = 0;
goto exit;
}
trp->rem_len += (c & 127) * trp->multiplier;
trp->multiplier *= 128;
} while ((c & 128) != 0);
rc = trp->len;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Helper function to read packet data from some source into a buffer, non-blocking
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
* @return integer MQTT packet type, 0 for call again, or -1 on error
* @note the whole message must fit into the caller's buffer
*/
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp)
{
int rc = -1, frc;
MQTTHeader header = {0};
switch(trp->state){
default:
trp->state = 0;
/*FALLTHROUGH*/
case 0:
/* read the header byte. This has the packet type in it */
if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)
goto exit;
if (frc == 0)
return 0;
trp->len = 0;
++trp->state;
/*FALLTHROUGH*/
/* read the remaining length. This is variable in itself */
case 1:
if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
goto exit;
if(frc == 0)
return 0;
trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */
if((trp->rem_len + trp->len) > buflen)
goto exit;
++trp->state;
/*FALLTHROUGH*/
case 2:
/* read the rest of the buffer using a callback to supply the rest of the data */
if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)
goto exit;
if (frc == 0)
return 0;
trp->rem_len -= frc;
trp->len += frc;
if(trp->rem_len)
return 0;
header.byte = buf[0];
rc = header.bits.type;
break;
}
exit:
trp->state = 0;
return rc;
}

View File

@ -0,0 +1,133 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTPACKET_H_
#define MQTTPACKET_H_
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#if defined(WIN32_DLL) || defined(WIN64_DLL)
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
#elif defined(LINUX_SO)
#define DLLImport extern
#define DLLExport __attribute__ ((visibility ("default")))
#else
#define DLLImport
#define DLLExport
#endif
enum errors
{
MQTTPACKET_BUFFER_TOO_SHORT = -2,
MQTTPACKET_READ_ERROR = -1,
MQTTPACKET_READ_COMPLETE
};
enum msgTypes
{
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
PINGREQ, PINGRESP, DISCONNECT
};
/**
* Bitfields for the MQTT header byte.
*/
typedef union
{
unsigned char byte; /**< the whole byte */
#if defined(REVERSED)
struct
{
unsigned int type : 4; /**< message type nibble */
unsigned int dup : 1; /**< DUP flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
unsigned int retain : 1; /**< retained flag bit */
} bits;
#else
struct
{
unsigned int retain : 1; /**< retained flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
unsigned int dup : 1; /**< DUP flag bit */
unsigned int type : 4; /**< message type nibble */
} bits;
#endif
} MQTTHeader;
typedef struct
{
int len;
char* data;
} MQTTLenString;
typedef struct
{
char* cstring;
MQTTLenString lenstring;
} MQTTString;
#define MQTTString_initializer {NULL, {0, NULL}}
int MQTTstrlen(MQTTString mqttstring);
#include "MQTTConnect.h"
#include "MQTTPublish.h"
#include "MQTTSubscribe.h"
#include "MQTTUnsubscribe.h"
#include "MQTTFormat.h"
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid);
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen);
int MQTTPacket_len(int rem_len);
int MQTTPacket_equals(MQTTString* a, char* b);
int MQTTPacket_encode(unsigned char* buf, int length);
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value);
int MQTTPacket_decodeBuf(unsigned char* buf, int* value);
int readInt(unsigned char** pptr);
char readChar(unsigned char** pptr);
void writeChar(unsigned char** pptr, char c);
void writeInt(unsigned char** pptr, int anInt);
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata);
void writeCString(unsigned char** pptr, const char* string);
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring);
DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int));
typedef struct {
int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */
void *sck; /* pointer to whatever the system may use to identify the transport */
int multiplier;
int rem_len;
int len;
char state;
}MQTTTransport;
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp);
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
}
#endif
#endif /* MQTTPACKET_H_ */

View File

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTPUBLISH_H_
#define MQTTPUBLISH_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
MQTTString topicName, unsigned char* payload, int payloadlen);
DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
unsigned char** payload, int* payloadlen, unsigned char* buf, int len);
DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid);
DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid);
DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid);
#endif /* MQTTPUBLISH_H_ */

View File

@ -0,0 +1,169 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT publish packet that would be produced using the supplied parameters
* @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
* @param topicName the topic name to be used in the publish
* @param payloadlen the length of the payload to be sent
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen)
{
int len = 0;
len += 2 + MQTTstrlen(topicName) + payloadlen;
if (qos > 0)
len += 2; /* packetid */
return len;
}
/**
* Serializes the supplied publish data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param dup integer - the MQTT dup flag
* @param qos integer - the MQTT QoS value
* @param retained integer - the MQTT retained flag
* @param packetid integer - the MQTT packet identifier
* @param topicName MQTTString - the MQTT topic in the publish
* @param payload byte buffer - the MQTT publish payload
* @param payloadlen integer - the length of the MQTT payload
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
MQTTString topicName, unsigned char* payload, int payloadlen)
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.bits.type = PUBLISH;
header.bits.dup = dup;
header.bits.qos = qos;
header.bits.retain = retained;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeMQTTString(&ptr, topicName);
if (qos > 0)
writeInt(&ptr, packetid);
memcpy(ptr, payload, payloadlen);
ptr += payloadlen;
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the ack packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param type the MQTT packet type
* @param dup the MQTT dup flag
* @param packetid the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 4)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.bits.type = packettype;
header.bits.dup = dup;
header.bits.qos = (packettype == PUBREL) ? 1 : 0;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
writeInt(&ptr, packetid);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a puback packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);
}
/**
* Serializes a pubrel packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);
}
/**
* Serializes a pubrel packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);
}

View File

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTSUBSCRIBE_H_
#define MQTTSUBSCRIBE_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[], int requestedQoSs[]);
DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid,
int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len);
DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs);
DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len);
#endif /* MQTTSUBSCRIBE_H_ */

View File

@ -0,0 +1,137 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters
* @param count the number of topic filter strings in topicFilters
* @param topicFilters the array of topic filter strings to be used in the publish
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[])
{
int i;
int len = 2; /* packetid */
for (i = 0; i < count; ++i)
len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */
return len;
}
/**
* Serializes the supplied subscribe data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied bufferr
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the topicFilters and reqQos arrays
* @param topicFilters - array of topic filter names
* @param requestedQoSs - array of requested QoS
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[])
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = 0;
int i = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = SUBSCRIBE;
header.bits.dup = dup;
header.bits.qos = 1;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
{
writeMQTTString(&ptr, topicFilters[i]);
writeChar(&ptr, requestedQoSs[i]);
}
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into suback data
* @param packetid returned integer - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the grantedQoSs array
* @param count returned integer - number of members in the grantedQoSs array
* @param grantedQoSs returned array of integers - the granted qualities of service
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != SUBACK)
goto exit;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (*count > maxcount)
{
rc = -1;
goto exit;
}
grantedQoSs[(*count)++] = readChar(&curdata);
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@ -0,0 +1,112 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Deserializes the supplied (wire) buffer into subscribe data
* @param dup integer returned - the MQTT dup flag
* @param packetid integer returned - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
* @param count - number of members in the topicFilters and requestedQoSs arrays
* @param topicFilters - array of topic filter names
* @param requestedQoSs - array of requested QoS
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
int requestedQoSs[], unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = -1;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != SUBSCRIBE)
goto exit;
*dup = header.bits.dup;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
goto exit;
if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */
goto exit;
requestedQoSs[*count] = readChar(&curdata);
(*count)++;
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the supplied suback data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the grantedQoSs array
* @param grantedQoSs - array of granted QoS
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs)
{
MQTTHeader header = {0};
int rc = -1;
unsigned char *ptr = buf;
int i;
FUNC_ENTRY;
if (buflen < 2 + count)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = SUBACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
writeChar(&ptr, grantedQoSs[i]);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTUNSUBSCRIBE_H_
#define MQTTUNSUBSCRIBE_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[]);
DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[],
unsigned char* buf, int len);
DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid);
DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len);
#endif /* MQTTUNSUBSCRIBE_H_ */

View File

@ -0,0 +1,106 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters
* @param count the number of topic filter strings in topicFilters
* @param topicFilters the array of topic filter strings to be used in the publish
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[])
{
int i;
int len = 2; /* packetid */
for (i = 0; i < count; ++i)
len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/
return len;
}
/**
* Serializes the supplied unsubscribe data into the supplied buffer, ready for sending
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the topicFilters array
* @param topicFilters - array of topic filter names
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[])
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = -1;
int i = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = UNSUBSCRIBE;
header.bits.dup = dup;
header.bits.qos = 1;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
writeMQTTString(&ptr, topicFilters[i]);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into unsuback data
* @param packetid returned integer - the MQTT packet identifier
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen)
{
unsigned char type = 0;
unsigned char dup = 0;
int rc = 0;
FUNC_ENTRY;
rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);
if (type == UNSUBACK)
rc = 1;
FUNC_EXIT_RC(rc);
return rc;
}

View File

@ -0,0 +1,102 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Deserializes the supplied (wire) buffer into unsubscribe data
* @param dup integer returned - the MQTT dup flag
* @param packetid integer returned - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
* @param count - number of members in the topicFilters and requestedQoSs arrays
* @param topicFilters - array of topic filter names
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
unsigned char* buf, int len)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != UNSUBSCRIBE)
goto exit;
*dup = header.bits.dup;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
goto exit;
(*count)++;
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the supplied unsuback data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = UNSUBACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
writeInt(&ptr, packetid);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - fix for bug #434081
*******************************************************************************/
#ifndef STACKTRACE_H_
#define STACKTRACE_H_
#include <stdio.h>
#define NOSTACKTRACE 1
#if defined(NOSTACKTRACE)
#define FUNC_ENTRY
#define FUNC_ENTRY_NOLOG
#define FUNC_ENTRY_MED
#define FUNC_ENTRY_MAX
#define FUNC_EXIT
#define FUNC_EXIT_NOLOG
#define FUNC_EXIT_MED
#define FUNC_EXIT_MAX
#define FUNC_EXIT_RC(x)
#define FUNC_EXIT_MED_RC(x)
#define FUNC_EXIT_MAX_RC(x)
#else
#if defined(WIN32)
#define inline __inline
#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)
#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)
#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)
#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)
#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)
#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)
#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)
#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)
#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)
#else
#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)
#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)
#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)
#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)
#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)
#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)
#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)
#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)
#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)
void StackTrace_entry(const char* name, int line, int trace);
void StackTrace_exit(const char* name, int line, void* return_value, int trace);
void StackTrace_printStack(FILE* dest);
char* StackTrace_get(unsigned long);
#endif
#endif
#endif /* STACKTRACE_H_ */

View File

@ -0,0 +1,169 @@
//*****************************************************************************
//! \file mqtt_interface.c
//! \brief Paho MQTT to WIZnet Chip interface implement file.
//! \details The process of porting an interface to use paho MQTT.
//! \version 1.0.0
//! \date 2016/12/06
//! \par Revision history
//! <2016/12/06> 1st Release
//!
//! \author Peter Bang & Justin Kim
//! \copyright
//!
//! Copyright (c) 2016, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * 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.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
#include "mqtt_interface.h"
#include "wizchip_conf.h"
unsigned long MilliTimer;
/*
* @brief MQTT MilliTimer handler
* @note MUST BE register to your system 1m Tick timer handler.
*/
void MilliTimer_Handler(void) {
MilliTimer++;
}
/*
* @brief Timer Initialize
* @param timer : pointer to a Timer structure
* that contains the configuration information for the Timer.
*/
void TimerInit(Timer* timer) {
timer->end_time = 0;
}
/*
* @brief expired Timer
* @param timer : pointer to a Timer structure
* that contains the configuration information for the Timer.
*/
char TimerIsExpired(Timer* timer) {
long left = timer->end_time - MilliTimer;
return (left < 0);
}
/*
* @brief Countdown millisecond Timer
* @param timer : pointer to a Timer structure
* that contains the configuration information for the Timer.
* timeout : setting timeout millisecond.
*/
void TimerCountdownMS(Timer* timer, unsigned int timeout) {
timer->end_time = MilliTimer + timeout;
}
/*
* @brief Countdown second Timer
* @param timer : pointer to a Timer structure
* that contains the configuration information for the Timer.
* timeout : setting timeout millisecond.
*/
void TimerCountdown(Timer* timer, unsigned int timeout) {
timer->end_time = MilliTimer + (timeout * 1000);
}
/*
* @brief left millisecond Timer
* @param timer : pointer to a Timer structure
* that contains the configuration information for the Timer.
*/
int TimerLeftMS(Timer* timer) {
long left = timer->end_time - MilliTimer;
return (left < 0) ? 0 : left;
}
/*
* @brief New network setting
* @param n : pointer to a Network structure
* that contains the configuration information for the Network.
* sn : socket number where x can be (0..7).
* @retval None
*/
void NewNetwork(Network* n, int sn) {
n->my_socket = sn;
n->mqttread = w5x00_read;
n->mqttwrite = w5x00_write;
n->disconnect = w5x00_disconnect;
}
/*
* @brief read function
* @param n : pointer to a Network structure
* that contains the configuration information for the Network.
* buffer : pointer to a read buffer.
* len : buffer length.
*/
int w5x00_read(Network* n, unsigned char* buffer, int len)
{
if((getSn_SR(n->my_socket) == SOCK_ESTABLISHED) && (getSn_RX_RSR(n->my_socket)>0))
return recv(n->my_socket, buffer, len);
}
/*
* @brief write function
* @param n : pointer to a Network structure
* that contains the configuration information for the Network.
* buffer : pointer to a read buffer.
* len : buffer length.
*/
int w5x00_write(Network* n, unsigned char* buffer, int len)
{
if(getSn_SR(n->my_socket) == SOCK_ESTABLISHED)
return send(n->my_socket, buffer, len);
}
/*
* @brief disconnect function
* @param n : pointer to a Network structure
* that contains the configuration information for the Network.
*/
void w5x00_disconnect(Network* n)
{
disconnect(n->my_socket);
}
/*
* @brief connect network function
* @param n : pointer to a Network structure
* that contains the configuration information for the Network.
* ip : server iP.
* port : server port.
*/
int ConnectNetwork(Network* n, char* ip, int port)
{
uint8_t myport = 12345;
socket(n->my_socket,Sn_MR_TCP,myport,0);
connect(n->my_socket,ip,port);
}

View File

@ -0,0 +1,260 @@
//*****************************************************************************
//! \file mqtt_interface.h
//! \brief Paho MQTT to WIZnet Chip interface Header file.
//! \details The process of porting an interface to use paho MQTT.
//! \version 1.0.0
//! \date 2016/12/06
//! \par Revision history
//! <2016/12/06> 1st Release
//!
//! \author Peter Bang & Justin Kim
//! \copyright
//!
//! Copyright (c) 2016, WIZnet Co., LTD.
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//! * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//! * 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.
//! * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************
/* MQTT subscribe Example.... W5500 + STM32F103(IoT board)
//Include: Board configuration
#include "IoTEVB.h"
//Include: MCU peripheral Library
#include "stm32f10x_rcc.h"
#include "stm32f10x.h"
//Include: W5500 iolibrary
#include "w5500.h"
#include "wizchip_conf.h"
#include "misc.h"
//Include: Internet iolibrary
#include "MQTTClient.h"
//Include: MCU Specific W5500 driver
#include "W5500HardwareDriver.h"
//Include: Standard IO Library
#include <stdio.h>
//Socket number defines
#define TCP_SOCKET 0
//Receive Buffer Size define
#define BUFFER_SIZE 2048
//Global variables
unsigned char targetIP[4] = {}; // mqtt server IP
unsigned int targetPort = 1883; // mqtt server port
uint8_t mac_address[6] = {};
wiz_NetInfo gWIZNETINFO = { .mac = {}, //user MAC
.ip = {}, //user IP
.sn = {},
.gw = {},
.dns = {},
.dhcp = NETINFO_STATIC};
unsigned char tempBuffer[BUFFER_SIZE] = {};
struct opts_struct
{
char* clientid;
int nodelimiter;
char* delimiter;
enum QoS qos;
char* username;
char* password;
char* host;
int port;
int showtopics;
} opts ={ (char*)"stdout-subscriber", 0, (char*)"\n", QOS0, NULL, NULL, targetIP, targetPort, 0 };
// @brief messageArrived callback function
void messageArrived(MessageData* md)
{
unsigned char testbuffer[100];
MQTTMessage* message = md->message;
if (opts.showtopics)
{
memcpy(testbuffer,(char*)message->payload,(int)message->payloadlen);
*(testbuffer + (int)message->payloadlen + 1) = "\n";
printf("%s\r\n",testbuffer);
}
if (opts.nodelimiter)
printf("%.*s", (int)message->payloadlen, (char*)message->payload);
else
printf("%.*s%s", (int)message->payloadlen, (char*)message->payload, opts.delimiter);
}
// @brief 1 millisecond Tick Timer setting
void NVIC_configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
SysTick_Config(72000);
NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Highest priority
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// @brief 1 millisecond Tick Timer Handler setting
void SysTick_Handler(void)
{
MilliTimer_Handler();
}
int main(void)
{
led_ctrl led1,led2;
int i;
int rc = 0;
unsigned char buf[100];
//Usart initialization for Debug.
USART1Initialze();
printf("USART initialized.\n\r");
I2C1Initialize();
printf("I2C initialized.\n\r");
MACEEP_Read(mac_address,0xfa,6);
printf("Mac address\n\r");
for(i = 0 ; i < 6 ; i++)
{
printf("%02x ",mac_address[i]);
}
printf("\n\r");
//LED initialization.
led_initialize();
led1 = led2 = ON;
led2Ctrl(led2);
led1Ctrl(led1);
//W5500 initialization.
W5500HardwareInitilize();
printf("W5500 hardware interface initialized.\n\r");
W5500Initialze();
printf("W5500 IC initialized.\n\r");
//Set network informations
wizchip_setnetinfo(&gWIZNETINFO);
setSHAR(mac_address);
print_network_information();
Network n;
MQTTClient c;
NewNetwork(&n, TCP_SOCKET);
ConnectNetwork(&n, targetIP, targetPort);
MQTTClientInit(&c,&n,1000,buf,100,tempBuffer,2048);
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.willFlag = 0;
data.MQTTVersion = 3;
data.clientID.cstring = opts.clientid;
data.username.cstring = opts.username;
data.password.cstring = opts.password;
data.keepAliveInterval = 60;
data.cleansession = 1;
rc = MQTTConnect(&c, &data);
printf("Connected %d\r\n", rc);
opts.showtopics = 1;
printf("Subscribing to %s\r\n", "hello/wiznet");
rc = MQTTSubscribe(&c, "hello/wiznet", opts.qos, messageArrived);
printf("Subscribed %d\r\n", rc);
while(1)
{
MQTTYield(&c, data.keepAliveInterval);
}
}
*/
#ifndef __MQTT_INTERFACE_H_
#define __MQTT_INTERFACE_H_
/*
* @brief MQTT MilliTimer handler
* @note MUST BE register to your system 1m Tick timer handler
*/
void MilliTimer_Handler(void);
/*
* @brief Timer structure
*/
typedef struct Timer Timer;
struct Timer {
unsigned long systick_period;
unsigned long end_time;
};
/*
* @brief Network structure
*/
typedef struct Network Network;
struct Network
{
int my_socket;
int (*mqttread) (Network*, unsigned char*, int, int);
int (*mqttwrite) (Network*, unsigned char*, int, int);
void (*disconnect) (Network*);
};
/*
* @brief Timer function
*/
void TimerInit(Timer*);
char TimerIsExpired(Timer*);
void TimerCountdownMS(Timer*, unsigned int);
void TimerCountdown(Timer*, unsigned int);
int TimerLeftMS(Timer*);
/*
* @brief Network interface porting
*/
int w5x00_read(Network*, unsigned char*, int);
int w5x00_write(Network*, unsigned char*, int);
void w5x00_disconnect(Network*);
void NewNetwork(Network* n, int sn);
int ConnectNetwork(Network*, char*, int);
#endif //__MQTT_INTERFACE_H_

View File

@ -132,7 +132,7 @@ void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx)
case 20: case 20:
seconds -= 1*3600; seconds -= 1*3600;
break; break;
case 21: // case 21: //<EFBFBD><EFBFBD>?
case 22: case 22:
break; break;
case 23: case 23:
@ -217,6 +217,8 @@ void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx)
void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf) void SNTP_init(uint8_t s, uint8_t *ntp_server, uint8_t tz, uint8_t *buf)
{ {
NTP_SOCKET = s;
NTPformat.dstaddr[0] = ntp_server[0]; NTPformat.dstaddr[0] = ntp_server[0];
NTPformat.dstaddr[1] = ntp_server[1]; NTPformat.dstaddr[1] = ntp_server[1];
NTPformat.dstaddr[2] = ntp_server[2]; NTPformat.dstaddr[2] = ntp_server[2];

View File

@ -9,8 +9,6 @@
#include "httpParser.h" #include "httpParser.h"
#include "httpUtil.h" #include "httpUtil.h"
#include "common.h"
#ifdef _USE_SDCARD_ #ifdef _USE_SDCARD_
#include "ff.h" // header file for FatFs library (FAT file system) #include "ff.h" // header file for FatFs library (FAT file system)
#endif #endif

View File

@ -1,6 +1,6 @@
#ioLibrary Driver #ioLibrary Driver
The ioLibrary means “Internet Offload Library” for WIZnet chip. It includes drivers and application protocols. The ioLibrary means “Internet Offload Library” for WIZnet chip. It includes drivers and application protocols.
The driver (ioLibrary) can be used for [W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start) application designs. These will be updated continuously. The driver (ioLibrary) can be used for the application design of WIZnet TCP/IP chips as [W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start), W5300, W5200 and W5100.
##ioLibrary ##ioLibrary
This driver provides the Berkeley Socket type APIs. This driver provides the Berkeley Socket type APIs.
@ -8,14 +8,49 @@ This driver provides the Berkeley Socket type APIs.
<!-- ioLibrary pic --> <!-- ioLibrary pic -->
![ioLibrary](http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:iolibrary_bsd.jpg "ioLibrary") ![ioLibrary](http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:iolibrary_bsd.jpg "ioLibrary")
- Ethernet : SOCKET APIs like BSD & WIZCHIP([W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start), W5200 and etc) Driver - Ethernet : SOCKET APIs like BSD & WIZCHIP([W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start) / W5300 / W5200 / W5100) Driver
- Internet : - Internet :
- DHCP client - DHCP client
- DNS client - DNS client
- FTP client
- FTP server
- SNMP agent/trap
- SNTP client
- TFTP client
- HTTP server
- MQTT Client
- Others will be added. - Others will be added.
## How to add an ioLibrary in project through github site. ## How to add an ioLibrary in project through github site.
- Example, refer to https://www.youtube.com/watch?v=mt815RBGdsA - Example, refer to https://www.youtube.com/watch?v=mt815RBGdsA
- [ioLibrary Doxygen doument](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/SOCKET_APIs_V2.0.chm) : Refer to **TODO** in this document
- Define what chip is used in **wizchip_conf.h**
- Define what Host I/F mode is used in **wizchip_conf.h**
## Revision History ## Revision History
Last release : Nov. 2014 * ioLibrary V3.1.1 Released : 14, Dec, 2016
* Bug fixed : In Socket.c Fixed MACraw & IPraw sendto function.
* ioLibrary V3.1.0 Released : 05, Dec, 2016
* Internet application protocol add to MQTT Client (using paho MQTT 3.11)
* ioLibrary V3.0.3 Released : 03, May, 2016
* In W5300, Fixed some compile errors in close(). Refer to M20160503
* In close(), replace socket() with some command sequences.
* ioLibrary V3.0.2 Released : 26, April, 2016
* Applied the erratum #1 in close() of socket.c (Refer to A20160426)
* ioLibrary V3.0.1 Released : 15, July, 2015
* Bug fixed : In W5100, Fixed CS control problem in read/write buffer with SPI. Refer to M20150715.
* ioLibrary V3.0 Released : 01, June, 2015
* Add to W5300
* Typing Error in comments
* Refer to 20150601 in sources.
* Type casting error Fixed : 09, April. 2015
In socket.c, send() : Refer to M20150409
* ioLibrary V2.0 released : April. 2015
* Added to W5100, W5200
* Correct to some typing error
* Fixed the warning of type casting.
* Last release : Nov. 2014

22
license.txt Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2014 WIZnet Co.,Ltd.
Copyright (c) WIZnet ioLibrary Project.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.