BSD style socket API for W5500.
Dependencies: W5500
Fork of Ethernet by
socket.c@2:ee0f7508fb5c, 2014-02-18 (annotated)
- Committer:
- xeon011
- Date:
- Tue Feb 18 05:41:48 2014 +0000
- Revision:
- 2:ee0f7508fb5c
- Parent:
- 0:9158fe13dc14
First release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
xeon011 | 0:9158fe13dc14 | 1 | //***************************************************************************** |
xeon011 | 0:9158fe13dc14 | 2 | // |
xeon011 | 0:9158fe13dc14 | 3 | //! \file socket.c |
xeon011 | 0:9158fe13dc14 | 4 | //! \brief SOCKET APIs Implements file. |
xeon011 | 0:9158fe13dc14 | 5 | //! \details SOCKET APIs like as Berkeley Socket APIs. |
xeon011 | 0:9158fe13dc14 | 6 | //! \version 1.0.0.0 |
xeon011 | 0:9158fe13dc14 | 7 | //! \date 2013/10/01 |
xeon011 | 0:9158fe13dc14 | 8 | //! \par Revision history |
xeon011 | 0:9158fe13dc14 | 9 | //! <2013/10/01> 1st Release |
xeon011 | 0:9158fe13dc14 | 10 | //! \author MidnightCow |
xeon011 | 0:9158fe13dc14 | 11 | //! \copyright |
xeon011 | 0:9158fe13dc14 | 12 | //! |
xeon011 | 0:9158fe13dc14 | 13 | //! Copyright (c) 2013, WIZnet Co., LTD. |
xeon011 | 0:9158fe13dc14 | 14 | //! All rights reserved. |
xeon011 | 0:9158fe13dc14 | 15 | //! |
xeon011 | 0:9158fe13dc14 | 16 | //! Redistribution and use in source and binary forms, with or without |
xeon011 | 0:9158fe13dc14 | 17 | //! modification, are permitted provided that the following conditions |
xeon011 | 0:9158fe13dc14 | 18 | //! are met: |
xeon011 | 0:9158fe13dc14 | 19 | //! |
xeon011 | 0:9158fe13dc14 | 20 | //! * Redistributions of source code must retain the above copyright |
xeon011 | 0:9158fe13dc14 | 21 | //! notice, this list of conditions and the following disclaimer. |
xeon011 | 0:9158fe13dc14 | 22 | //! * Redistributions in binary form must reproduce the above copyright |
xeon011 | 0:9158fe13dc14 | 23 | //! notice, this list of conditions and the following disclaimer in the |
xeon011 | 0:9158fe13dc14 | 24 | //! documentation and/or other materials provided with the distribution. |
xeon011 | 0:9158fe13dc14 | 25 | //! * Neither the name of the <ORGANIZATION> nor the names of its |
xeon011 | 0:9158fe13dc14 | 26 | //! contributors may be used to endorse or promote products derived |
xeon011 | 0:9158fe13dc14 | 27 | //! from this software without specific prior written permission. |
xeon011 | 0:9158fe13dc14 | 28 | //! |
xeon011 | 0:9158fe13dc14 | 29 | //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
xeon011 | 0:9158fe13dc14 | 30 | //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
xeon011 | 0:9158fe13dc14 | 31 | //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
xeon011 | 0:9158fe13dc14 | 32 | //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
xeon011 | 0:9158fe13dc14 | 33 | //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
xeon011 | 0:9158fe13dc14 | 34 | //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
xeon011 | 0:9158fe13dc14 | 35 | //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
xeon011 | 0:9158fe13dc14 | 36 | //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
xeon011 | 0:9158fe13dc14 | 37 | //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
xeon011 | 0:9158fe13dc14 | 38 | //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
xeon011 | 0:9158fe13dc14 | 39 | //! THE POSSIBILITY OF SUCH DAMAGE. |
xeon011 | 0:9158fe13dc14 | 40 | // |
xeon011 | 0:9158fe13dc14 | 41 | //***************************************************************************** |
xeon011 | 0:9158fe13dc14 | 42 | #include "socket.h" |
xeon011 | 0:9158fe13dc14 | 43 | |
xeon011 | 0:9158fe13dc14 | 44 | #define SOCK_ANY_PORT_NUM 0xC000; |
xeon011 | 0:9158fe13dc14 | 45 | |
xeon011 | 0:9158fe13dc14 | 46 | static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; |
xeon011 | 0:9158fe13dc14 | 47 | static uint16_t sock_io_mode = 0; |
xeon011 | 0:9158fe13dc14 | 48 | static uint16_t sock_is_sending = 0; |
xeon011 | 0:9158fe13dc14 | 49 | static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; |
xeon011 | 0:9158fe13dc14 | 50 | |
xeon011 | 0:9158fe13dc14 | 51 | #define CHECK_SOCKNUM() \ |
xeon011 | 0:9158fe13dc14 | 52 | do{ \ |
xeon011 | 0:9158fe13dc14 | 53 | if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ |
xeon011 | 0:9158fe13dc14 | 54 | }while(0); \ |
xeon011 | 0:9158fe13dc14 | 55 | |
xeon011 | 0:9158fe13dc14 | 56 | #define CHECK_SOCKMODE(mode) \ |
xeon011 | 0:9158fe13dc14 | 57 | do{ \ |
xeon011 | 0:9158fe13dc14 | 58 | if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ |
xeon011 | 0:9158fe13dc14 | 59 | }while(0); \ |
xeon011 | 0:9158fe13dc14 | 60 | |
xeon011 | 0:9158fe13dc14 | 61 | #define CHECK_SOCKINIT() \ |
xeon011 | 0:9158fe13dc14 | 62 | do{ \ |
xeon011 | 0:9158fe13dc14 | 63 | if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ |
xeon011 | 0:9158fe13dc14 | 64 | }while(0); \ |
xeon011 | 0:9158fe13dc14 | 65 | |
xeon011 | 0:9158fe13dc14 | 66 | #define CHECK_SOCKDATA() \ |
xeon011 | 0:9158fe13dc14 | 67 | do{ \ |
xeon011 | 0:9158fe13dc14 | 68 | if(len == 0) return SOCKERR_DATALEN; \ |
xeon011 | 0:9158fe13dc14 | 69 | }while(0); \ |
xeon011 | 0:9158fe13dc14 | 70 | |
xeon011 | 0:9158fe13dc14 | 71 | |
xeon011 | 0:9158fe13dc14 | 72 | |
xeon011 | 0:9158fe13dc14 | 73 | int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) |
xeon011 | 0:9158fe13dc14 | 74 | { |
xeon011 | 0:9158fe13dc14 | 75 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 76 | switch(protocol) |
xeon011 | 0:9158fe13dc14 | 77 | { |
xeon011 | 0:9158fe13dc14 | 78 | case Sn_MR_TCP : |
xeon011 | 0:9158fe13dc14 | 79 | case Sn_MR_UDP : |
xeon011 | 0:9158fe13dc14 | 80 | case Sn_MR_MACRAW : |
xeon011 | 0:9158fe13dc14 | 81 | break; |
xeon011 | 0:9158fe13dc14 | 82 | #if ( _WIZCHIP_ < 5200 ) |
xeon011 | 0:9158fe13dc14 | 83 | case Sn_MR_IPRAW : |
xeon011 | 0:9158fe13dc14 | 84 | case Sn_MR_PPPoE : |
xeon011 | 0:9158fe13dc14 | 85 | break; |
xeon011 | 0:9158fe13dc14 | 86 | #endif |
xeon011 | 0:9158fe13dc14 | 87 | default : |
xeon011 | 0:9158fe13dc14 | 88 | return SOCKERR_SOCKMODE; |
xeon011 | 0:9158fe13dc14 | 89 | } |
xeon011 | 0:9158fe13dc14 | 90 | if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; |
xeon011 | 0:9158fe13dc14 | 91 | #if _WIZCHIP_ == 5200 |
xeon011 | 0:9158fe13dc14 | 92 | if(flag & 0x10) return SOCKERR_SOCKFLAG; |
xeon011 | 0:9158fe13dc14 | 93 | #endif |
xeon011 | 0:9158fe13dc14 | 94 | |
xeon011 | 0:9158fe13dc14 | 95 | if(flag != 0) |
xeon011 | 0:9158fe13dc14 | 96 | { |
xeon011 | 0:9158fe13dc14 | 97 | switch(protocol) |
xeon011 | 0:9158fe13dc14 | 98 | { |
xeon011 | 0:9158fe13dc14 | 99 | case Sn_MR_TCP: |
xeon011 | 0:9158fe13dc14 | 100 | if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; |
xeon011 | 0:9158fe13dc14 | 101 | break; |
xeon011 | 0:9158fe13dc14 | 102 | case Sn_MR_UDP: |
xeon011 | 0:9158fe13dc14 | 103 | if(flag & SF_IGMP_VER2) |
xeon011 | 0:9158fe13dc14 | 104 | { |
xeon011 | 0:9158fe13dc14 | 105 | if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; |
xeon011 | 0:9158fe13dc14 | 106 | } |
xeon011 | 0:9158fe13dc14 | 107 | #if _WIZCHIP_ == 5500 |
xeon011 | 0:9158fe13dc14 | 108 | if(flag & SF_UNI_BLOCK) |
xeon011 | 0:9158fe13dc14 | 109 | { |
xeon011 | 0:9158fe13dc14 | 110 | if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; |
xeon011 | 0:9158fe13dc14 | 111 | } |
xeon011 | 0:9158fe13dc14 | 112 | #endif |
xeon011 | 0:9158fe13dc14 | 113 | break; |
xeon011 | 0:9158fe13dc14 | 114 | default: |
xeon011 | 0:9158fe13dc14 | 115 | break; |
xeon011 | 0:9158fe13dc14 | 116 | } |
xeon011 | 0:9158fe13dc14 | 117 | } |
xeon011 | 0:9158fe13dc14 | 118 | close(sn); |
xeon011 | 0:9158fe13dc14 | 119 | setSn_MR(sn, (protocol | (flag & 0xF0))); |
xeon011 | 0:9158fe13dc14 | 120 | if(!port) |
xeon011 | 0:9158fe13dc14 | 121 | { |
xeon011 | 0:9158fe13dc14 | 122 | port = sock_any_port++; |
xeon011 | 0:9158fe13dc14 | 123 | if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; |
xeon011 | 0:9158fe13dc14 | 124 | } |
xeon011 | 0:9158fe13dc14 | 125 | setSn_PORT(sn,port); |
xeon011 | 0:9158fe13dc14 | 126 | setSn_CR(sn,Sn_CR_OPEN); |
xeon011 | 0:9158fe13dc14 | 127 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 128 | sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); |
xeon011 | 0:9158fe13dc14 | 129 | sock_is_sending &= ~(1<<sn); |
xeon011 | 0:9158fe13dc14 | 130 | sock_remained_size[sn] = 0; |
xeon011 | 0:9158fe13dc14 | 131 | while(getSn_SR(sn) == SOCK_CLOSED); |
xeon011 | 0:9158fe13dc14 | 132 | return (int8_t)sn; |
xeon011 | 0:9158fe13dc14 | 133 | } |
xeon011 | 0:9158fe13dc14 | 134 | |
xeon011 | 0:9158fe13dc14 | 135 | int8_t close(uint8_t sn) |
xeon011 | 0:9158fe13dc14 | 136 | { |
xeon011 | 0:9158fe13dc14 | 137 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 138 | |
xeon011 | 0:9158fe13dc14 | 139 | setSn_CR(sn,Sn_CR_CLOSE); |
xeon011 | 0:9158fe13dc14 | 140 | /* wait to process the command... */ |
xeon011 | 0:9158fe13dc14 | 141 | while( getSn_CR(sn) ); |
xeon011 | 0:9158fe13dc14 | 142 | /* clear all interrupt of the socket. */ |
xeon011 | 0:9158fe13dc14 | 143 | setSn_IR(sn, 0xFF); |
xeon011 | 0:9158fe13dc14 | 144 | sock_is_sending &= ~(1<<sn); |
xeon011 | 0:9158fe13dc14 | 145 | sock_remained_size[sn] = 0; |
xeon011 | 0:9158fe13dc14 | 146 | while(getSn_SR(sn) != SOCK_CLOSED); |
xeon011 | 0:9158fe13dc14 | 147 | return SOCK_OK; |
xeon011 | 0:9158fe13dc14 | 148 | } |
xeon011 | 0:9158fe13dc14 | 149 | |
xeon011 | 0:9158fe13dc14 | 150 | int8_t listen(uint8_t sn) |
xeon011 | 0:9158fe13dc14 | 151 | { |
xeon011 | 0:9158fe13dc14 | 152 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 153 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 154 | CHECK_SOCKINIT(); |
xeon011 | 0:9158fe13dc14 | 155 | setSn_CR(sn,Sn_CR_LISTEN); |
xeon011 | 0:9158fe13dc14 | 156 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 157 | while(getSn_SR(sn) != SOCK_LISTEN) |
xeon011 | 0:9158fe13dc14 | 158 | { |
xeon011 | 0:9158fe13dc14 | 159 | if(getSn_CR(sn) == SOCK_CLOSED) |
xeon011 | 0:9158fe13dc14 | 160 | { |
xeon011 | 0:9158fe13dc14 | 161 | close(sn); |
xeon011 | 0:9158fe13dc14 | 162 | return SOCKERR_SOCKCLOSED; |
xeon011 | 0:9158fe13dc14 | 163 | } |
xeon011 | 0:9158fe13dc14 | 164 | } |
xeon011 | 0:9158fe13dc14 | 165 | return SOCK_OK; |
xeon011 | 0:9158fe13dc14 | 166 | } |
xeon011 | 0:9158fe13dc14 | 167 | |
xeon011 | 0:9158fe13dc14 | 168 | |
xeon011 | 0:9158fe13dc14 | 169 | int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port) |
xeon011 | 0:9158fe13dc14 | 170 | { |
xeon011 | 0:9158fe13dc14 | 171 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 172 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 173 | CHECK_SOCKINIT(); |
xeon011 | 0:9158fe13dc14 | 174 | if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; |
xeon011 | 0:9158fe13dc14 | 175 | if(port == 0) return SOCKERR_PORTZERO; |
xeon011 | 0:9158fe13dc14 | 176 | setSn_DIPR(sn,addr); |
xeon011 | 0:9158fe13dc14 | 177 | setSn_DPORT(sn,port); |
xeon011 | 0:9158fe13dc14 | 178 | // setSUBR(); // set the subnet mask register |
xeon011 | 0:9158fe13dc14 | 179 | setSn_CR(sn,Sn_CR_CONNECT); |
xeon011 | 0:9158fe13dc14 | 180 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 181 | if(sock_io_mode & (1<<sn)) return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 182 | while(getSn_SR(sn) != SOCK_ESTABLISHED) |
xeon011 | 0:9158fe13dc14 | 183 | { |
xeon011 | 0:9158fe13dc14 | 184 | if (getSn_IR(sn) & Sn_IR_TIMEOUT) |
xeon011 | 0:9158fe13dc14 | 185 | { |
xeon011 | 0:9158fe13dc14 | 186 | setSn_IR(sn, Sn_IR_TIMEOUT); |
xeon011 | 0:9158fe13dc14 | 187 | return SOCKERR_TIMEOUT; |
xeon011 | 0:9158fe13dc14 | 188 | } |
xeon011 | 0:9158fe13dc14 | 189 | } |
xeon011 | 0:9158fe13dc14 | 190 | // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100 |
xeon011 | 0:9158fe13dc14 | 191 | return SOCK_OK; |
xeon011 | 0:9158fe13dc14 | 192 | } |
xeon011 | 0:9158fe13dc14 | 193 | |
xeon011 | 0:9158fe13dc14 | 194 | int8_t disconnect(uint8_t sn) |
xeon011 | 0:9158fe13dc14 | 195 | { |
xeon011 | 0:9158fe13dc14 | 196 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 197 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 198 | setSn_CR(sn,Sn_CR_DISCON); |
xeon011 | 0:9158fe13dc14 | 199 | /* wait to process the command... */ |
xeon011 | 0:9158fe13dc14 | 200 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 201 | sock_is_sending &= ~(1<<sn); |
xeon011 | 0:9158fe13dc14 | 202 | if(sock_io_mode & (1<<sn)) return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 203 | while(getSn_SR(sn) != SOCK_CLOSED) |
xeon011 | 0:9158fe13dc14 | 204 | { |
xeon011 | 0:9158fe13dc14 | 205 | if(getSn_IR(sn) & Sn_IR_TIMEOUT) |
xeon011 | 0:9158fe13dc14 | 206 | { |
xeon011 | 0:9158fe13dc14 | 207 | close(sn); |
xeon011 | 0:9158fe13dc14 | 208 | return SOCKERR_TIMEOUT; |
xeon011 | 0:9158fe13dc14 | 209 | } |
xeon011 | 0:9158fe13dc14 | 210 | } |
xeon011 | 0:9158fe13dc14 | 211 | return SOCK_OK; |
xeon011 | 0:9158fe13dc14 | 212 | } |
xeon011 | 0:9158fe13dc14 | 213 | |
xeon011 | 0:9158fe13dc14 | 214 | int32_t send(uint8_t sn, uint8_t * buf, uint16_t len) |
xeon011 | 0:9158fe13dc14 | 215 | { |
xeon011 | 0:9158fe13dc14 | 216 | uint8_t tmp=0; |
xeon011 | 0:9158fe13dc14 | 217 | uint16_t freesize=0; |
xeon011 | 0:9158fe13dc14 | 218 | |
xeon011 | 0:9158fe13dc14 | 219 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 220 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 221 | CHECK_SOCKDATA(); |
xeon011 | 0:9158fe13dc14 | 222 | tmp = getSn_SR(sn); |
xeon011 | 0:9158fe13dc14 | 223 | if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS; |
xeon011 | 0:9158fe13dc14 | 224 | if( sock_is_sending & (1<<sn) ) |
xeon011 | 0:9158fe13dc14 | 225 | { |
xeon011 | 0:9158fe13dc14 | 226 | tmp = getSn_IR(sn); |
xeon011 | 0:9158fe13dc14 | 227 | if(tmp & Sn_IR_SENDOK) |
xeon011 | 0:9158fe13dc14 | 228 | { |
xeon011 | 0:9158fe13dc14 | 229 | setSn_IR(sn, Sn_IR_SENDOK); |
xeon011 | 0:9158fe13dc14 | 230 | sock_is_sending &= ~(1<<sn); |
xeon011 | 0:9158fe13dc14 | 231 | } |
xeon011 | 0:9158fe13dc14 | 232 | else if(tmp & Sn_IR_TIMEOUT) |
xeon011 | 0:9158fe13dc14 | 233 | { |
xeon011 | 0:9158fe13dc14 | 234 | close(sn); |
xeon011 | 0:9158fe13dc14 | 235 | return SOCKERR_TIMEOUT; |
xeon011 | 0:9158fe13dc14 | 236 | } |
xeon011 | 0:9158fe13dc14 | 237 | else return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 238 | } |
xeon011 | 0:9158fe13dc14 | 239 | freesize = getSn_TxMAX(sn); |
xeon011 | 0:9158fe13dc14 | 240 | if (len > freesize) len = freesize; // check size not to exceed MAX size. |
xeon011 | 0:9158fe13dc14 | 241 | while(1) |
xeon011 | 0:9158fe13dc14 | 242 | { |
xeon011 | 0:9158fe13dc14 | 243 | freesize = getSn_TX_FSR(sn); |
xeon011 | 0:9158fe13dc14 | 244 | tmp = getSn_SR(sn); |
xeon011 | 0:9158fe13dc14 | 245 | if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) |
xeon011 | 0:9158fe13dc14 | 246 | { |
xeon011 | 0:9158fe13dc14 | 247 | close(sn); |
xeon011 | 0:9158fe13dc14 | 248 | return SOCKERR_SOCKSTATUS; |
xeon011 | 0:9158fe13dc14 | 249 | } |
xeon011 | 0:9158fe13dc14 | 250 | if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 251 | if(len <= freesize) break; |
xeon011 | 0:9158fe13dc14 | 252 | } |
xeon011 | 0:9158fe13dc14 | 253 | wiz_send_data(sn, buf, len); |
xeon011 | 0:9158fe13dc14 | 254 | setSn_CR(sn,Sn_CR_SEND); |
xeon011 | 0:9158fe13dc14 | 255 | /* wait to process the command... */ |
xeon011 | 0:9158fe13dc14 | 256 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 257 | sock_is_sending |= (1 << sn); |
xeon011 | 0:9158fe13dc14 | 258 | /* |
xeon011 | 0:9158fe13dc14 | 259 | if(sock_io_mode & (1<<sn)) return len; |
xeon011 | 0:9158fe13dc14 | 260 | while( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) !=Sn_IR_SENDOK ) |
xeon011 | 0:9158fe13dc14 | 261 | { |
xeon011 | 0:9158fe13dc14 | 262 | if(tmp & Sn_IR_TIMEOUT) |
xeon011 | 0:9158fe13dc14 | 263 | { |
xeon011 | 0:9158fe13dc14 | 264 | close(sn); |
xeon011 | 0:9158fe13dc14 | 265 | return SOCKERR_TIMEOUT; |
xeon011 | 0:9158fe13dc14 | 266 | } |
xeon011 | 0:9158fe13dc14 | 267 | } |
xeon011 | 0:9158fe13dc14 | 268 | setSn_IR(sn, Sn_IR_SENDOK); |
xeon011 | 0:9158fe13dc14 | 269 | */ |
xeon011 | 0:9158fe13dc14 | 270 | return len; |
xeon011 | 0:9158fe13dc14 | 271 | } |
xeon011 | 0:9158fe13dc14 | 272 | |
xeon011 | 0:9158fe13dc14 | 273 | |
xeon011 | 0:9158fe13dc14 | 274 | int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) |
xeon011 | 0:9158fe13dc14 | 275 | { |
xeon011 | 0:9158fe13dc14 | 276 | uint8_t tmp = 0; |
xeon011 | 0:9158fe13dc14 | 277 | uint16_t recvsize = 0; |
xeon011 | 0:9158fe13dc14 | 278 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 279 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 280 | CHECK_SOCKDATA(); |
xeon011 | 0:9158fe13dc14 | 281 | |
xeon011 | 0:9158fe13dc14 | 282 | recvsize = getSn_RxMAX(sn); |
xeon011 | 0:9158fe13dc14 | 283 | if(recvsize < len) len = recvsize; |
xeon011 | 0:9158fe13dc14 | 284 | while(1) |
xeon011 | 0:9158fe13dc14 | 285 | { |
xeon011 | 0:9158fe13dc14 | 286 | recvsize = getSn_RX_RSR(sn); |
xeon011 | 0:9158fe13dc14 | 287 | tmp = getSn_SR(sn); |
xeon011 | 0:9158fe13dc14 | 288 | if (tmp != SOCK_ESTABLISHED) |
xeon011 | 0:9158fe13dc14 | 289 | { |
xeon011 | 0:9158fe13dc14 | 290 | if(tmp == SOCK_CLOSE_WAIT) |
xeon011 | 0:9158fe13dc14 | 291 | { |
xeon011 | 0:9158fe13dc14 | 292 | if(recvsize != 0) break; |
xeon011 | 0:9158fe13dc14 | 293 | else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) |
xeon011 | 0:9158fe13dc14 | 294 | { |
xeon011 | 0:9158fe13dc14 | 295 | close(sn); |
xeon011 | 0:9158fe13dc14 | 296 | return SOCKERR_SOCKSTATUS; |
xeon011 | 0:9158fe13dc14 | 297 | } |
xeon011 | 0:9158fe13dc14 | 298 | } |
xeon011 | 0:9158fe13dc14 | 299 | else |
xeon011 | 0:9158fe13dc14 | 300 | { |
xeon011 | 0:9158fe13dc14 | 301 | close(sn); |
xeon011 | 0:9158fe13dc14 | 302 | return SOCKERR_SOCKSTATUS; |
xeon011 | 0:9158fe13dc14 | 303 | } |
xeon011 | 0:9158fe13dc14 | 304 | } |
xeon011 | 0:9158fe13dc14 | 305 | if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 306 | if(recvsize != 0) break; |
xeon011 | 0:9158fe13dc14 | 307 | }; |
xeon011 | 0:9158fe13dc14 | 308 | if(recvsize < len) len = recvsize; |
xeon011 | 0:9158fe13dc14 | 309 | wiz_recv_data(sn, buf, len); |
xeon011 | 0:9158fe13dc14 | 310 | setSn_CR(sn,Sn_CR_RECV); |
xeon011 | 0:9158fe13dc14 | 311 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 312 | return len; |
xeon011 | 0:9158fe13dc14 | 313 | } |
xeon011 | 0:9158fe13dc14 | 314 | |
xeon011 | 0:9158fe13dc14 | 315 | int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) |
xeon011 | 0:9158fe13dc14 | 316 | { |
xeon011 | 0:9158fe13dc14 | 317 | uint8_t tmp = 0; |
xeon011 | 0:9158fe13dc14 | 318 | uint16_t freesize = 0; |
xeon011 | 0:9158fe13dc14 | 319 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 320 | //CHECK_SOCKMODE(Sn_MR_UDP); |
xeon011 | 0:9158fe13dc14 | 321 | switch(getSn_MR(sn) & 0x0F) |
xeon011 | 0:9158fe13dc14 | 322 | { |
xeon011 | 0:9158fe13dc14 | 323 | case Sn_MR_UDP: |
xeon011 | 0:9158fe13dc14 | 324 | case Sn_MR_MACRAW: |
xeon011 | 0:9158fe13dc14 | 325 | break; |
xeon011 | 0:9158fe13dc14 | 326 | default: |
xeon011 | 0:9158fe13dc14 | 327 | return SOCKERR_SOCKMODE; |
xeon011 | 0:9158fe13dc14 | 328 | } |
xeon011 | 0:9158fe13dc14 | 329 | CHECK_SOCKDATA(); |
xeon011 | 0:9158fe13dc14 | 330 | if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; |
xeon011 | 0:9158fe13dc14 | 331 | if(port == 0) return SOCKERR_PORTZERO; |
xeon011 | 0:9158fe13dc14 | 332 | tmp = getSn_SR(sn); |
xeon011 | 0:9158fe13dc14 | 333 | if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; |
xeon011 | 0:9158fe13dc14 | 334 | |
xeon011 | 0:9158fe13dc14 | 335 | if( sock_is_sending & (1<<sn) ) |
xeon011 | 0:9158fe13dc14 | 336 | { |
xeon011 | 0:9158fe13dc14 | 337 | tmp = getSn_IR(sn); |
xeon011 | 0:9158fe13dc14 | 338 | if(tmp & Sn_IR_SENDOK) |
xeon011 | 0:9158fe13dc14 | 339 | { |
xeon011 | 0:9158fe13dc14 | 340 | setSn_IR(sn, Sn_IR_SENDOK); |
xeon011 | 0:9158fe13dc14 | 341 | sock_is_sending &= ~(1<<sn); |
xeon011 | 0:9158fe13dc14 | 342 | } |
xeon011 | 0:9158fe13dc14 | 343 | else if(tmp & Sn_IR_TIMEOUT) |
xeon011 | 0:9158fe13dc14 | 344 | { |
xeon011 | 0:9158fe13dc14 | 345 | close(sn); |
xeon011 | 0:9158fe13dc14 | 346 | return SOCKERR_TIMEOUT; |
xeon011 | 0:9158fe13dc14 | 347 | } |
xeon011 | 0:9158fe13dc14 | 348 | else return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 349 | } |
xeon011 | 0:9158fe13dc14 | 350 | |
xeon011 | 0:9158fe13dc14 | 351 | setSn_DIPR(sn,addr); |
xeon011 | 0:9158fe13dc14 | 352 | setSn_DPORT(sn,port); |
xeon011 | 0:9158fe13dc14 | 353 | freesize = getSn_TxMAX(sn); |
xeon011 | 0:9158fe13dc14 | 354 | if (len > freesize) len = freesize; // check size not to exceed MAX size. |
xeon011 | 0:9158fe13dc14 | 355 | while(1) |
xeon011 | 0:9158fe13dc14 | 356 | { |
xeon011 | 0:9158fe13dc14 | 357 | freesize = getSn_TX_FSR(sn); |
xeon011 | 0:9158fe13dc14 | 358 | if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; |
xeon011 | 0:9158fe13dc14 | 359 | if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 360 | if(len <= freesize) break; |
xeon011 | 0:9158fe13dc14 | 361 | }; |
xeon011 | 0:9158fe13dc14 | 362 | wiz_send_data(sn, buf, len); |
xeon011 | 0:9158fe13dc14 | 363 | // setSUBR(); // set the subnet mask register |
xeon011 | 0:9158fe13dc14 | 364 | setSn_CR(sn,Sn_CR_SEND); |
xeon011 | 0:9158fe13dc14 | 365 | /* wait to process the command... */ |
xeon011 | 0:9158fe13dc14 | 366 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 367 | sock_is_sending |= (1<<sn); |
xeon011 | 0:9158fe13dc14 | 368 | #if 0 |
xeon011 | 0:9158fe13dc14 | 369 | if(sock_io_mode & (1<<sn)) return len; |
xeon011 | 0:9158fe13dc14 | 370 | while ( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) != Sn_IR_SENDOK ) |
xeon011 | 0:9158fe13dc14 | 371 | { |
xeon011 | 0:9158fe13dc14 | 372 | if(tmp & Sn_IR_TIMEOUT) |
xeon011 | 0:9158fe13dc14 | 373 | { |
xeon011 | 0:9158fe13dc14 | 374 | setSn_IR(sn, (Sn_IR_SENDOK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */ |
xeon011 | 0:9158fe13dc14 | 375 | return SOCKERR_TIMEOUT; |
xeon011 | 0:9158fe13dc14 | 376 | } |
xeon011 | 0:9158fe13dc14 | 377 | } |
xeon011 | 0:9158fe13dc14 | 378 | // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100 |
xeon011 | 0:9158fe13dc14 | 379 | setSn_IR(sn, Sn_IR_SENDOK); |
xeon011 | 0:9158fe13dc14 | 380 | #endif |
xeon011 | 0:9158fe13dc14 | 381 | return len; |
xeon011 | 0:9158fe13dc14 | 382 | } |
xeon011 | 0:9158fe13dc14 | 383 | |
xeon011 | 0:9158fe13dc14 | 384 | |
xeon011 | 0:9158fe13dc14 | 385 | |
xeon011 | 0:9158fe13dc14 | 386 | int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t* packinfo) |
xeon011 | 0:9158fe13dc14 | 387 | { |
xeon011 | 0:9158fe13dc14 | 388 | uint8_t mr; |
xeon011 | 0:9158fe13dc14 | 389 | uint8_t head[8]; |
xeon011 | 0:9158fe13dc14 | 390 | uint16_t pack_len=0; |
xeon011 | 0:9158fe13dc14 | 391 | |
xeon011 | 0:9158fe13dc14 | 392 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 393 | //CHECK_SOCKMODE(Sn_MR_UDP); |
xeon011 | 0:9158fe13dc14 | 394 | switch((mr=getSn_MR(sn)) & 0x0F) |
xeon011 | 0:9158fe13dc14 | 395 | { |
xeon011 | 0:9158fe13dc14 | 396 | case Sn_MR_UDP: |
xeon011 | 0:9158fe13dc14 | 397 | case Sn_MR_MACRAW: |
xeon011 | 0:9158fe13dc14 | 398 | break; |
xeon011 | 0:9158fe13dc14 | 399 | #if ( _WIZCHIP_ < 5200 ) |
xeon011 | 0:9158fe13dc14 | 400 | case Sn_MR_IPRAW: |
xeon011 | 0:9158fe13dc14 | 401 | case Sn_MR_PPPoE: |
xeon011 | 0:9158fe13dc14 | 402 | break; |
xeon011 | 0:9158fe13dc14 | 403 | #endif |
xeon011 | 0:9158fe13dc14 | 404 | default: |
xeon011 | 0:9158fe13dc14 | 405 | return SOCKERR_SOCKMODE; |
xeon011 | 0:9158fe13dc14 | 406 | } |
xeon011 | 0:9158fe13dc14 | 407 | CHECK_SOCKDATA(); |
xeon011 | 0:9158fe13dc14 | 408 | if(sock_remained_size[sn] == 0) |
xeon011 | 0:9158fe13dc14 | 409 | { |
xeon011 | 0:9158fe13dc14 | 410 | while(1) |
xeon011 | 0:9158fe13dc14 | 411 | { |
xeon011 | 0:9158fe13dc14 | 412 | pack_len = getSn_RX_RSR(sn); |
xeon011 | 0:9158fe13dc14 | 413 | if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; |
xeon011 | 0:9158fe13dc14 | 414 | if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; |
xeon011 | 0:9158fe13dc14 | 415 | if(pack_len != 0) break; |
xeon011 | 0:9158fe13dc14 | 416 | }; |
xeon011 | 0:9158fe13dc14 | 417 | } |
xeon011 | 0:9158fe13dc14 | 418 | *packinfo = 0x00; |
xeon011 | 0:9158fe13dc14 | 419 | switch (mr & 0x07) |
xeon011 | 0:9158fe13dc14 | 420 | { |
xeon011 | 0:9158fe13dc14 | 421 | case Sn_MR_UDP : |
xeon011 | 0:9158fe13dc14 | 422 | if(sock_remained_size[sn] == 0) |
xeon011 | 0:9158fe13dc14 | 423 | { |
xeon011 | 0:9158fe13dc14 | 424 | wiz_recv_data(sn, head, 8); |
xeon011 | 0:9158fe13dc14 | 425 | setSn_CR(sn,Sn_CR_RECV); |
xeon011 | 0:9158fe13dc14 | 426 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 427 | // read peer's IP address, port number & packet length |
xeon011 | 0:9158fe13dc14 | 428 | addr[0] = head[0]; |
xeon011 | 0:9158fe13dc14 | 429 | addr[1] = head[1]; |
xeon011 | 0:9158fe13dc14 | 430 | addr[2] = head[2]; |
xeon011 | 0:9158fe13dc14 | 431 | addr[3] = head[3]; |
xeon011 | 0:9158fe13dc14 | 432 | *port = head[4]; |
xeon011 | 0:9158fe13dc14 | 433 | *port = (*port << 8) + head[5]; |
xeon011 | 0:9158fe13dc14 | 434 | sock_remained_size[sn] = head[6]; |
xeon011 | 0:9158fe13dc14 | 435 | sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; |
xeon011 | 0:9158fe13dc14 | 436 | *packinfo = 0x80; |
xeon011 | 0:9158fe13dc14 | 437 | } |
xeon011 | 0:9158fe13dc14 | 438 | if(len < sock_remained_size[sn]) pack_len = len; |
xeon011 | 0:9158fe13dc14 | 439 | else pack_len = sock_remained_size[sn]; |
xeon011 | 0:9158fe13dc14 | 440 | // |
xeon011 | 0:9158fe13dc14 | 441 | // Need to packet length check (default 1472) |
xeon011 | 0:9158fe13dc14 | 442 | // |
xeon011 | 0:9158fe13dc14 | 443 | wiz_recv_data(sn, buf, pack_len); // data copy. |
xeon011 | 0:9158fe13dc14 | 444 | break; |
xeon011 | 0:9158fe13dc14 | 445 | case Sn_MR_MACRAW : |
xeon011 | 0:9158fe13dc14 | 446 | if(sock_remained_size[sn] == 0) |
xeon011 | 0:9158fe13dc14 | 447 | { |
xeon011 | 0:9158fe13dc14 | 448 | wiz_recv_data(sn, head, 2); |
xeon011 | 0:9158fe13dc14 | 449 | setSn_CR(sn,Sn_CR_RECV); |
xeon011 | 0:9158fe13dc14 | 450 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 451 | // read peer's IP address, port number & packet length |
xeon011 | 0:9158fe13dc14 | 452 | sock_remained_size[sn] = head[0]; |
xeon011 | 0:9158fe13dc14 | 453 | sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1]; |
xeon011 | 0:9158fe13dc14 | 454 | if(sock_remained_size[sn] > 1514) |
xeon011 | 0:9158fe13dc14 | 455 | { |
xeon011 | 0:9158fe13dc14 | 456 | close(sn); |
xeon011 | 0:9158fe13dc14 | 457 | return SOCKFATAL_PACKLEN; |
xeon011 | 0:9158fe13dc14 | 458 | } |
xeon011 | 0:9158fe13dc14 | 459 | } |
xeon011 | 0:9158fe13dc14 | 460 | if(len < sock_remained_size[sn]) pack_len = len; |
xeon011 | 0:9158fe13dc14 | 461 | else pack_len = sock_remained_size[sn]; |
xeon011 | 0:9158fe13dc14 | 462 | wiz_recv_data(sn,buf,pack_len); |
xeon011 | 0:9158fe13dc14 | 463 | break; |
xeon011 | 0:9158fe13dc14 | 464 | #if ( _WIZCHIP_ < 5200 ) |
xeon011 | 0:9158fe13dc14 | 465 | case Sn_MR_IPRAW: |
xeon011 | 0:9158fe13dc14 | 466 | if(sock_remained_size[sn] == 0) |
xeon011 | 0:9158fe13dc14 | 467 | { |
xeon011 | 0:9158fe13dc14 | 468 | wiz_recv_data(sn, head, 6); |
xeon011 | 0:9158fe13dc14 | 469 | setSn_CR(sn,Sn_CR_RECV); |
xeon011 | 0:9158fe13dc14 | 470 | while(getSn_CR(sn)); |
xeon011 | 0:9158fe13dc14 | 471 | addr[0] = head[0]; |
xeon011 | 0:9158fe13dc14 | 472 | addr[1] = head[1]; |
xeon011 | 0:9158fe13dc14 | 473 | addr[2] = head[2]; |
xeon011 | 0:9158fe13dc14 | 474 | addr[3] = head[3]; |
xeon011 | 0:9158fe13dc14 | 475 | sock_remained_size[sn] = head[4]; |
xeon011 | 0:9158fe13dc14 | 476 | sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; |
xeon011 | 0:9158fe13dc14 | 477 | *packinfo = 0x80; |
xeon011 | 0:9158fe13dc14 | 478 | } |
xeon011 | 0:9158fe13dc14 | 479 | // |
xeon011 | 0:9158fe13dc14 | 480 | // Need to packet length check |
xeon011 | 0:9158fe13dc14 | 481 | // |
xeon011 | 0:9158fe13dc14 | 482 | if(len < sock_remained_size[sn]) pack_len = len; |
xeon011 | 0:9158fe13dc14 | 483 | else pack_len = sock_remained_size[sn]; |
xeon011 | 0:9158fe13dc14 | 484 | wiz_recv_data(sn, buf, pack_len); // data copy. |
xeon011 | 0:9158fe13dc14 | 485 | break; |
xeon011 | 0:9158fe13dc14 | 486 | #endif |
xeon011 | 0:9158fe13dc14 | 487 | default: |
xeon011 | 0:9158fe13dc14 | 488 | wiz_recv_ignore(sn, pack_len); // data copy. |
xeon011 | 0:9158fe13dc14 | 489 | sock_remained_size[sn] = pack_len; |
xeon011 | 0:9158fe13dc14 | 490 | break; |
xeon011 | 0:9158fe13dc14 | 491 | } |
xeon011 | 0:9158fe13dc14 | 492 | setSn_CR(sn,Sn_CR_RECV); |
xeon011 | 0:9158fe13dc14 | 493 | /* wait to process the command... */ |
xeon011 | 0:9158fe13dc14 | 494 | while(getSn_CR(sn)) ; |
xeon011 | 0:9158fe13dc14 | 495 | sock_remained_size[sn] -= pack_len; |
xeon011 | 0:9158fe13dc14 | 496 | if(sock_remained_size[sn] != 0) *packinfo |= 0x01; |
xeon011 | 0:9158fe13dc14 | 497 | return pack_len; |
xeon011 | 0:9158fe13dc14 | 498 | } |
xeon011 | 0:9158fe13dc14 | 499 | |
xeon011 | 0:9158fe13dc14 | 500 | |
xeon011 | 0:9158fe13dc14 | 501 | int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg) |
xeon011 | 0:9158fe13dc14 | 502 | { |
xeon011 | 0:9158fe13dc14 | 503 | uint8_t tmp = 0; |
xeon011 | 0:9158fe13dc14 | 504 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 505 | switch(cstype) |
xeon011 | 0:9158fe13dc14 | 506 | { |
xeon011 | 0:9158fe13dc14 | 507 | case CS_SET_IOMODE: |
xeon011 | 0:9158fe13dc14 | 508 | tmp = *((uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 509 | if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn); |
xeon011 | 0:9158fe13dc14 | 510 | else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn); |
xeon011 | 0:9158fe13dc14 | 511 | else return SOCKERR_ARG; |
xeon011 | 0:9158fe13dc14 | 512 | break; |
xeon011 | 0:9158fe13dc14 | 513 | case CS_GET_IOMODE: |
xeon011 | 0:9158fe13dc14 | 514 | *((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; |
xeon011 | 0:9158fe13dc14 | 515 | break; |
xeon011 | 0:9158fe13dc14 | 516 | case CS_GET_MAXTXBUF: |
xeon011 | 0:9158fe13dc14 | 517 | *((uint16_t*)arg) = getSn_TxMAX(sn); |
xeon011 | 0:9158fe13dc14 | 518 | break; |
xeon011 | 0:9158fe13dc14 | 519 | case CS_GET_MAXRXBUF: |
xeon011 | 0:9158fe13dc14 | 520 | *((uint16_t*)arg) = getSn_RxMAX(sn); |
xeon011 | 0:9158fe13dc14 | 521 | break; |
xeon011 | 0:9158fe13dc14 | 522 | case CS_CLR_INTERRUPT: |
xeon011 | 0:9158fe13dc14 | 523 | if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; |
xeon011 | 0:9158fe13dc14 | 524 | setSn_IR(sn,*(uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 525 | break; |
xeon011 | 0:9158fe13dc14 | 526 | case CS_GET_INTERRUPT: |
xeon011 | 0:9158fe13dc14 | 527 | *((uint8_t*)arg) = getSn_IR(sn); |
xeon011 | 0:9158fe13dc14 | 528 | break; |
xeon011 | 0:9158fe13dc14 | 529 | case CS_SET_INTMASK: |
xeon011 | 0:9158fe13dc14 | 530 | if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; |
xeon011 | 0:9158fe13dc14 | 531 | setSn_IMR(sn,*(uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 532 | break; |
xeon011 | 0:9158fe13dc14 | 533 | case CS_GET_INTMASK: |
xeon011 | 0:9158fe13dc14 | 534 | *((uint8_t*)arg) = getSn_IMR(sn); |
xeon011 | 0:9158fe13dc14 | 535 | default: |
xeon011 | 0:9158fe13dc14 | 536 | return SOCKERR_ARG; |
xeon011 | 0:9158fe13dc14 | 537 | } |
xeon011 | 0:9158fe13dc14 | 538 | return SOCK_OK; |
xeon011 | 0:9158fe13dc14 | 539 | } |
xeon011 | 0:9158fe13dc14 | 540 | |
xeon011 | 0:9158fe13dc14 | 541 | int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg) |
xeon011 | 0:9158fe13dc14 | 542 | { |
xeon011 | 0:9158fe13dc14 | 543 | uint8_t tmp; |
xeon011 | 0:9158fe13dc14 | 544 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 545 | switch(sotype) |
xeon011 | 0:9158fe13dc14 | 546 | { |
xeon011 | 0:9158fe13dc14 | 547 | case SO_TTL: |
xeon011 | 0:9158fe13dc14 | 548 | setSn_TTL(sn,*(uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 549 | break; |
xeon011 | 0:9158fe13dc14 | 550 | case SO_TOS: |
xeon011 | 0:9158fe13dc14 | 551 | setSn_TOS(sn,*(uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 552 | break; |
xeon011 | 0:9158fe13dc14 | 553 | case SO_MSS: |
xeon011 | 0:9158fe13dc14 | 554 | setSn_MSSR(sn,*(uint16_t*)arg); |
xeon011 | 0:9158fe13dc14 | 555 | break; |
xeon011 | 0:9158fe13dc14 | 556 | case SO_DESTIP: |
xeon011 | 0:9158fe13dc14 | 557 | setSn_DIPR(sn, (uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 558 | break; |
xeon011 | 0:9158fe13dc14 | 559 | case SO_DESTPORT: |
xeon011 | 0:9158fe13dc14 | 560 | setSn_DPORT(sn, *(uint16_t*)arg); |
xeon011 | 0:9158fe13dc14 | 561 | break; |
xeon011 | 0:9158fe13dc14 | 562 | #if _WIZCHIP_ != 5100 |
xeon011 | 0:9158fe13dc14 | 563 | case SO_KEEPALIVESEND: |
xeon011 | 0:9158fe13dc14 | 564 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 565 | #if _WIZCHIP_ > 5200 |
xeon011 | 0:9158fe13dc14 | 566 | if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; |
xeon011 | 0:9158fe13dc14 | 567 | #endif |
xeon011 | 0:9158fe13dc14 | 568 | setSn_CR(sn,Sn_CR_SEND_KEEP); |
xeon011 | 0:9158fe13dc14 | 569 | while((tmp = getSn_CR(sn)) != 0) |
xeon011 | 0:9158fe13dc14 | 570 | { |
xeon011 | 0:9158fe13dc14 | 571 | if (getSn_IR(sn) & Sn_IR_TIMEOUT) |
xeon011 | 0:9158fe13dc14 | 572 | { |
xeon011 | 0:9158fe13dc14 | 573 | setSn_IR(sn, Sn_IR_TIMEOUT); |
xeon011 | 0:9158fe13dc14 | 574 | return SOCKERR_TIMEOUT; |
xeon011 | 0:9158fe13dc14 | 575 | } |
xeon011 | 0:9158fe13dc14 | 576 | } |
xeon011 | 0:9158fe13dc14 | 577 | break; |
xeon011 | 0:9158fe13dc14 | 578 | #if _WIZCHIP_ > 5200 |
xeon011 | 0:9158fe13dc14 | 579 | case SO_KEEPALIVEAUTO: |
xeon011 | 0:9158fe13dc14 | 580 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 581 | setSn_KPALVTR(sn,*(uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 582 | break; |
xeon011 | 0:9158fe13dc14 | 583 | #endif |
xeon011 | 0:9158fe13dc14 | 584 | #endif |
xeon011 | 0:9158fe13dc14 | 585 | default: |
xeon011 | 0:9158fe13dc14 | 586 | return SOCKERR_ARG; |
xeon011 | 0:9158fe13dc14 | 587 | } |
xeon011 | 0:9158fe13dc14 | 588 | return SOCK_OK; |
xeon011 | 0:9158fe13dc14 | 589 | } |
xeon011 | 0:9158fe13dc14 | 590 | |
xeon011 | 0:9158fe13dc14 | 591 | int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg) |
xeon011 | 0:9158fe13dc14 | 592 | { |
xeon011 | 0:9158fe13dc14 | 593 | CHECK_SOCKNUM(); |
xeon011 | 0:9158fe13dc14 | 594 | switch(sotype) |
xeon011 | 0:9158fe13dc14 | 595 | { |
xeon011 | 0:9158fe13dc14 | 596 | case SO_FLAG: |
xeon011 | 0:9158fe13dc14 | 597 | *(uint8_t*)arg = getSn_MR(sn) & 0xF0; |
xeon011 | 0:9158fe13dc14 | 598 | break; |
xeon011 | 0:9158fe13dc14 | 599 | case SO_TTL: |
xeon011 | 0:9158fe13dc14 | 600 | *(uint8_t*) arg = getSn_TTL(sn); |
xeon011 | 0:9158fe13dc14 | 601 | break; |
xeon011 | 0:9158fe13dc14 | 602 | case SO_TOS: |
xeon011 | 0:9158fe13dc14 | 603 | *(uint8_t*) arg = getSn_TOS(sn); |
xeon011 | 0:9158fe13dc14 | 604 | break; |
xeon011 | 0:9158fe13dc14 | 605 | case SO_MSS: |
xeon011 | 0:9158fe13dc14 | 606 | *(uint8_t*) arg = getSn_MSSR(sn); |
xeon011 | 0:9158fe13dc14 | 607 | case SO_DESTIP: |
xeon011 | 0:9158fe13dc14 | 608 | getSn_DIPR(sn, (uint8_t*)arg); |
xeon011 | 0:9158fe13dc14 | 609 | break; |
xeon011 | 0:9158fe13dc14 | 610 | case SO_DESTPORT: |
xeon011 | 0:9158fe13dc14 | 611 | *(uint16_t*) arg = getSn_DPORT(sn); |
xeon011 | 0:9158fe13dc14 | 612 | break; |
xeon011 | 0:9158fe13dc14 | 613 | #if _WIZCHIP_ > 5200 |
xeon011 | 0:9158fe13dc14 | 614 | case SO_KEEPALIVEAUTO: |
xeon011 | 0:9158fe13dc14 | 615 | CHECK_SOCKMODE(Sn_MR_TCP); |
xeon011 | 0:9158fe13dc14 | 616 | *(uint16_t*) arg = getSn_KPALVTR(sn); |
xeon011 | 0:9158fe13dc14 | 617 | break; |
xeon011 | 0:9158fe13dc14 | 618 | #endif |
xeon011 | 0:9158fe13dc14 | 619 | case SO_SENDBUF: |
xeon011 | 0:9158fe13dc14 | 620 | *(uint16_t*) arg = getSn_TX_FSR(sn); |
xeon011 | 0:9158fe13dc14 | 621 | case SO_RECVBUF: |
xeon011 | 0:9158fe13dc14 | 622 | *(uint16_t*) arg = getSn_RX_RSR(sn); |
xeon011 | 0:9158fe13dc14 | 623 | case SO_STATUS: |
xeon011 | 0:9158fe13dc14 | 624 | *(uint8_t*) arg = getSn_SR(sn); |
xeon011 | 0:9158fe13dc14 | 625 | break; |
xeon011 | 0:9158fe13dc14 | 626 | case SO_REMAINSIZE: |
xeon011 | 0:9158fe13dc14 | 627 | if(getSn_MR(sn) == Sn_MR_TCP) |
xeon011 | 0:9158fe13dc14 | 628 | *(uint16_t*)arg = getSn_RX_RSR(sn); |
xeon011 | 0:9158fe13dc14 | 629 | else |
xeon011 | 0:9158fe13dc14 | 630 | *(uint16_t*)arg = sock_remained_size[sn]; |
xeon011 | 0:9158fe13dc14 | 631 | break; |
xeon011 | 0:9158fe13dc14 | 632 | default: |
xeon011 | 0:9158fe13dc14 | 633 | return SOCKERR_SOCKOPT; |
xeon011 | 0:9158fe13dc14 | 634 | } |
xeon011 | 0:9158fe13dc14 | 635 | return SOCK_OK; |
xeon011 | 0:9158fe13dc14 | 636 | } |