Programme Nucleo RS485 - Modbus TCP/IP (ACP 40)

Fork of Modbus by Cam Marshall

Committer:
TomTom83
Date:
Fri Jul 06 11:45:57 2018 +0000
Revision:
2:b6ae32d99b4a
Parent:
1:390d9808cdde
Programme RS485 - Modbus TCP/IP (ACP40)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TomTom83 1:390d9808cdde 1 /*
TomTom83 1:390d9808cdde 2 * FreeModbus Libary: lwIP Port
TomTom83 1:390d9808cdde 3 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
TomTom83 1:390d9808cdde 4 *
TomTom83 1:390d9808cdde 5 * This library is free software; you can redistribute it and/or
TomTom83 1:390d9808cdde 6 * modify it under the terms of the GNU Lesser General Public
TomTom83 1:390d9808cdde 7 * License as published by the Free Software Foundation; either
TomTom83 1:390d9808cdde 8 * version 2.1 of the License, or (at your option) any later version.
TomTom83 1:390d9808cdde 9 *
TomTom83 1:390d9808cdde 10 * This library is distributed in the hope that it will be useful,
TomTom83 1:390d9808cdde 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
TomTom83 1:390d9808cdde 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
TomTom83 1:390d9808cdde 13 * Lesser General Public License for more details.
TomTom83 1:390d9808cdde 14 *
TomTom83 1:390d9808cdde 15 * You should have received a copy of the GNU Lesser General Public
TomTom83 1:390d9808cdde 16 * License along with this library; if not, write to the Free Software
TomTom83 1:390d9808cdde 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
TomTom83 1:390d9808cdde 18 *
TomTom83 1:390d9808cdde 19 * File: $Id: porttcp.c,v 1.2 2006/09/04 14:39:20 wolti Exp $
TomTom83 1:390d9808cdde 20 */
TomTom83 1:390d9808cdde 21
TomTom83 1:390d9808cdde 22 /* ----------------------- System includes ----------------------------------*/
TomTom83 1:390d9808cdde 23 #include <stdio.h>
TomTom83 1:390d9808cdde 24 #include "string.h"
TomTom83 1:390d9808cdde 25
TomTom83 1:390d9808cdde 26 #include "port.h"
TomTom83 1:390d9808cdde 27
TomTom83 1:390d9808cdde 28 /* ----------------------- lwIP includes ------------------------------------*/
TomTom83 1:390d9808cdde 29 #include "lwip/api.h"
TomTom83 1:390d9808cdde 30 #include "lwip/tcp.h"
TomTom83 1:390d9808cdde 31
TomTom83 1:390d9808cdde 32 /* ----------------------- Modbus includes ----------------------------------*/
TomTom83 1:390d9808cdde 33 #include "mb.h"
TomTom83 1:390d9808cdde 34 #include "mbport.h"
TomTom83 1:390d9808cdde 35
TomTom83 1:390d9808cdde 36 /* ----------------------- MBAP Header --------------------------------------*/
TomTom83 1:390d9808cdde 37 #define MB_TCP_UID 6
TomTom83 1:390d9808cdde 38 #define MB_TCP_LEN 4
TomTom83 1:390d9808cdde 39 #define MB_TCP_FUNC 7
TomTom83 1:390d9808cdde 40
TomTom83 1:390d9808cdde 41 /* ----------------------- Defines -----------------------------------------*/
TomTom83 1:390d9808cdde 42 #define MB_TCP_DEFAULT_PORT 502 /* TCP listening port. */
TomTom83 1:390d9808cdde 43 #define MB_TCP_BUF_SIZE ( 256 + 7 ) /* Must hold a complete Modbus TCP frame. */
TomTom83 1:390d9808cdde 44
TomTom83 1:390d9808cdde 45 /* ----------------------- Prototypes ---------------------------------------*/
TomTom83 1:390d9808cdde 46 void vMBPortEventClose( void ){};
TomTom83 1:390d9808cdde 47 void vMBPortLog( eMBPortLogLevel eLevel, const CHAR * szModule,
TomTom83 1:390d9808cdde 48 const CHAR * szFmt, ... );
TomTom83 1:390d9808cdde 49
TomTom83 1:390d9808cdde 50 /* ----------------------- Static variables ---------------------------------*/
TomTom83 1:390d9808cdde 51 static struct tcp_pcb *pxPCBListen;
TomTom83 1:390d9808cdde 52 static struct tcp_pcb *pxPCBClient;
TomTom83 1:390d9808cdde 53
TomTom83 1:390d9808cdde 54 static UCHAR aucTCPBuf[MB_TCP_BUF_SIZE];
TomTom83 1:390d9808cdde 55 static USHORT usTCPBufPos;
TomTom83 1:390d9808cdde 56
TomTom83 1:390d9808cdde 57 /* ----------------------- Static functions ---------------------------------*/
TomTom83 1:390d9808cdde 58 static err_t prvxMBTCPPortAccept( void *pvArg, struct tcp_pcb *pxPCB, err_t xErr );
TomTom83 1:390d9808cdde 59 static err_t prvxMBTCPPortReceive( void *pvArg, struct tcp_pcb *pxPCB, struct pbuf *p,
TomTom83 1:390d9808cdde 60 err_t xErr );
TomTom83 1:390d9808cdde 61 static void prvvMBTCPPortError( void *pvArg, err_t xErr );
TomTom83 1:390d9808cdde 62
TomTom83 1:390d9808cdde 63 /* ----------------------- Begin implementation -----------------------------*/
TomTom83 1:390d9808cdde 64 BOOL
TomTom83 1:390d9808cdde 65 xMBTCPPortInit( USHORT usTCPPort )
TomTom83 1:390d9808cdde 66 {
TomTom83 1:390d9808cdde 67 struct tcp_pcb *pxPCBListenNew, *pxPCBListenOld;
TomTom83 1:390d9808cdde 68 BOOL bOkay = FALSE;
TomTom83 1:390d9808cdde 69 USHORT usPort;
TomTom83 1:390d9808cdde 70
TomTom83 1:390d9808cdde 71 if( usTCPPort == 0 )
TomTom83 1:390d9808cdde 72 {
TomTom83 1:390d9808cdde 73 usPort = MB_TCP_DEFAULT_PORT;
TomTom83 1:390d9808cdde 74 }
TomTom83 1:390d9808cdde 75 else
TomTom83 1:390d9808cdde 76 {
TomTom83 1:390d9808cdde 77 usPort = ( USHORT ) usTCPPort;
TomTom83 1:390d9808cdde 78 }
TomTom83 1:390d9808cdde 79
TomTom83 1:390d9808cdde 80 if( ( pxPCBListenNew = pxPCBListenOld = tcp_new( ) ) == NULL )
TomTom83 1:390d9808cdde 81 {
TomTom83 1:390d9808cdde 82 /* Can't create TCP socket. */
TomTom83 1:390d9808cdde 83 bOkay = FALSE;
TomTom83 1:390d9808cdde 84 }
TomTom83 1:390d9808cdde 85 else if( tcp_bind( pxPCBListenNew, IP_ADDR_ANY, ( u16_t ) usPort ) != ERR_OK )
TomTom83 1:390d9808cdde 86 {
TomTom83 1:390d9808cdde 87 /* Bind failed - Maybe illegal port value or in use. */
TomTom83 1:390d9808cdde 88 ( void )tcp_close( pxPCBListenOld );
TomTom83 1:390d9808cdde 89 bOkay = FALSE;
TomTom83 1:390d9808cdde 90 }
TomTom83 1:390d9808cdde 91 else if( ( pxPCBListenNew = tcp_listen( pxPCBListenNew ) ) == NULL )
TomTom83 1:390d9808cdde 92 {
TomTom83 1:390d9808cdde 93 ( void )tcp_close( pxPCBListenOld );
TomTom83 1:390d9808cdde 94 bOkay = FALSE;
TomTom83 1:390d9808cdde 95 }
TomTom83 1:390d9808cdde 96 else
TomTom83 1:390d9808cdde 97 {
TomTom83 1:390d9808cdde 98 /* Register callback function for new clients. */
TomTom83 1:390d9808cdde 99 tcp_accept( pxPCBListenNew, prvxMBTCPPortAccept );
TomTom83 1:390d9808cdde 100
TomTom83 1:390d9808cdde 101 /* Everything okay. Set global variable. */
TomTom83 1:390d9808cdde 102 pxPCBListen = pxPCBListenNew;
TomTom83 1:390d9808cdde 103
TomTom83 1:390d9808cdde 104 #ifdef MB_TCP_DEBUG
TomTom83 1:390d9808cdde 105 vMBPortLog( MB_LOG_DEBUG, "MBTCP-ACCEPT", "Protocol stack ready.\r\n" );
TomTom83 1:390d9808cdde 106 #endif
TomTom83 1:390d9808cdde 107 }
TomTom83 1:390d9808cdde 108 bOkay = TRUE;
TomTom83 1:390d9808cdde 109 return bOkay;
TomTom83 1:390d9808cdde 110 }
TomTom83 1:390d9808cdde 111
TomTom83 1:390d9808cdde 112 void
TomTom83 1:390d9808cdde 113 prvvMBPortReleaseClient( struct tcp_pcb *pxPCB )
TomTom83 1:390d9808cdde 114 {
TomTom83 1:390d9808cdde 115 if( pxPCB != NULL )
TomTom83 1:390d9808cdde 116 {
TomTom83 1:390d9808cdde 117 if( tcp_close( pxPCB ) != ERR_OK )
TomTom83 1:390d9808cdde 118 {
TomTom83 1:390d9808cdde 119 tcp_abort( pxPCB );
TomTom83 1:390d9808cdde 120 }
TomTom83 1:390d9808cdde 121 // vPortEnterCritical( );
TomTom83 1:390d9808cdde 122 if( pxPCB == pxPCBClient )
TomTom83 1:390d9808cdde 123 {
TomTom83 1:390d9808cdde 124 #ifdef MB_TCP_DEBUG
TomTom83 1:390d9808cdde 125 vMBPortLog( MB_LOG_DEBUG, "MBTCP-CLOSE", "Closed connection to %d.%d.%d.%d.\r\n",
TomTom83 1:390d9808cdde 126 ip4_addr1( &( pxPCB->remote_ip ) ),
TomTom83 1:390d9808cdde 127 ip4_addr2( &( pxPCB->remote_ip ) ),
TomTom83 1:390d9808cdde 128 ip4_addr3( &( pxPCB->remote_ip ) ), ip4_addr4( &( pxPCB->remote_ip ) ) );
TomTom83 1:390d9808cdde 129 #endif
TomTom83 1:390d9808cdde 130 pxPCBClient = NULL;
TomTom83 1:390d9808cdde 131 }
TomTom83 1:390d9808cdde 132 if( pxPCB == pxPCBListen )
TomTom83 1:390d9808cdde 133 {
TomTom83 1:390d9808cdde 134 pxPCBListen = NULL;
TomTom83 1:390d9808cdde 135 }
TomTom83 1:390d9808cdde 136 //vPortExitCritical( );
TomTom83 1:390d9808cdde 137 }
TomTom83 1:390d9808cdde 138 }
TomTom83 1:390d9808cdde 139 void
TomTom83 1:390d9808cdde 140 vMBTCPPortClose( )
TomTom83 1:390d9808cdde 141 {
TomTom83 1:390d9808cdde 142 /* Shutdown any open client sockets. */
TomTom83 1:390d9808cdde 143 prvvMBPortReleaseClient( pxPCBClient );
TomTom83 1:390d9808cdde 144
TomTom83 1:390d9808cdde 145 /* Shutdown or listening socket. */
TomTom83 1:390d9808cdde 146 prvvMBPortReleaseClient( pxPCBListen );
TomTom83 1:390d9808cdde 147
TomTom83 1:390d9808cdde 148 /* Release resources for the event queue. */
TomTom83 1:390d9808cdde 149 vMBPortEventClose( );
TomTom83 1:390d9808cdde 150 }
TomTom83 1:390d9808cdde 151
TomTom83 1:390d9808cdde 152 void
TomTom83 1:390d9808cdde 153 vMBTCPPortDisable( void )
TomTom83 1:390d9808cdde 154 {
TomTom83 1:390d9808cdde 155 prvvMBPortReleaseClient( pxPCBClient );
TomTom83 1:390d9808cdde 156 }
TomTom83 1:390d9808cdde 157
TomTom83 1:390d9808cdde 158 err_t
TomTom83 1:390d9808cdde 159 prvxMBTCPPortAccept( void *pvArg, struct tcp_pcb *pxPCB, err_t xErr )
TomTom83 1:390d9808cdde 160 {
TomTom83 1:390d9808cdde 161 err_t error;
TomTom83 1:390d9808cdde 162
TomTom83 1:390d9808cdde 163 if( xErr != ERR_OK )
TomTom83 1:390d9808cdde 164 {
TomTom83 1:390d9808cdde 165 return xErr;
TomTom83 1:390d9808cdde 166 }
TomTom83 1:390d9808cdde 167
TomTom83 1:390d9808cdde 168 /* We can handle only one client. */
TomTom83 1:390d9808cdde 169 if( pxPCBClient == NULL )
TomTom83 1:390d9808cdde 170 {
TomTom83 1:390d9808cdde 171 /* Register the client. */
TomTom83 1:390d9808cdde 172 pxPCBClient = pxPCB;
TomTom83 1:390d9808cdde 173
TomTom83 1:390d9808cdde 174 /* Set up the receive function prvxMBTCPPortReceive( ) to be called when data
TomTom83 1:390d9808cdde 175 * arrives.
TomTom83 1:390d9808cdde 176 */
TomTom83 1:390d9808cdde 177 tcp_recv( pxPCB, prvxMBTCPPortReceive );
TomTom83 1:390d9808cdde 178
TomTom83 1:390d9808cdde 179 /* Register error handler. */
TomTom83 1:390d9808cdde 180 tcp_err( pxPCB, prvvMBTCPPortError );
TomTom83 1:390d9808cdde 181
TomTom83 1:390d9808cdde 182 /* Set callback argument later used in the error handler. */
TomTom83 1:390d9808cdde 183 tcp_arg( pxPCB, pxPCB );
TomTom83 1:390d9808cdde 184
TomTom83 1:390d9808cdde 185 /* Reset the buffers and state variables. */
TomTom83 1:390d9808cdde 186 usTCPBufPos = 0;
TomTom83 1:390d9808cdde 187
TomTom83 1:390d9808cdde 188 #ifdef MB_TCP_DEBUG
TomTom83 1:390d9808cdde 189 vMBPortLog( MB_LOG_DEBUG, "MBTCP-ACCEPT", "Accepted new client %d.%d.%d.%d\r\n",
TomTom83 1:390d9808cdde 190 ip4_addr1( &( pxPCB->remote_ip ) ),
TomTom83 1:390d9808cdde 191 ip4_addr2( &( pxPCB->remote_ip ) ),
TomTom83 1:390d9808cdde 192 ip4_addr3( &( pxPCB->remote_ip ) ), ip4_addr4( &( pxPCB->remote_ip ) ) );
TomTom83 1:390d9808cdde 193 #endif
TomTom83 1:390d9808cdde 194
TomTom83 1:390d9808cdde 195 error = ERR_OK;
TomTom83 1:390d9808cdde 196 }
TomTom83 1:390d9808cdde 197 else
TomTom83 1:390d9808cdde 198 {
TomTom83 1:390d9808cdde 199 prvvMBPortReleaseClient( pxPCB );
TomTom83 1:390d9808cdde 200 error = ERR_OK;
TomTom83 1:390d9808cdde 201 }
TomTom83 1:390d9808cdde 202 return error;
TomTom83 1:390d9808cdde 203 }
TomTom83 1:390d9808cdde 204
TomTom83 1:390d9808cdde 205 /* Called in case of an unrecoverable error. In any case we drop the client
TomTom83 1:390d9808cdde 206 * connection. */
TomTom83 1:390d9808cdde 207 void
TomTom83 1:390d9808cdde 208 prvvMBTCPPortError( void *pvArg, err_t xErr )
TomTom83 1:390d9808cdde 209 {
TomTom83 1:390d9808cdde 210 struct tcp_pcb *pxPCB = (struct tcp_pcb *)pvArg;
TomTom83 1:390d9808cdde 211
TomTom83 1:390d9808cdde 212 if( pxPCB != NULL )
TomTom83 1:390d9808cdde 213 {
TomTom83 1:390d9808cdde 214 #ifdef MB_TCP_DEBUG
TomTom83 1:390d9808cdde 215 vMBPortLog( MB_LOG_DEBUG, "MBTCP-ERROR", "Error with client connection! Droping it.\r\n" );
TomTom83 1:390d9808cdde 216 #endif
TomTom83 1:390d9808cdde 217 prvvMBPortReleaseClient( pxPCB );
TomTom83 1:390d9808cdde 218 }
TomTom83 1:390d9808cdde 219 }
TomTom83 1:390d9808cdde 220
TomTom83 1:390d9808cdde 221 err_t
TomTom83 1:390d9808cdde 222 prvxMBTCPPortReceive( void *pvArg, struct tcp_pcb *pxPCB, struct pbuf *p, err_t xErr )
TomTom83 1:390d9808cdde 223 {
TomTom83 1:390d9808cdde 224 USHORT usLength;
TomTom83 1:390d9808cdde 225
TomTom83 1:390d9808cdde 226 err_t error = xErr;
TomTom83 1:390d9808cdde 227
TomTom83 1:390d9808cdde 228 if( error != ERR_OK )
TomTom83 1:390d9808cdde 229 {
TomTom83 1:390d9808cdde 230 return error;
TomTom83 1:390d9808cdde 231 }
TomTom83 1:390d9808cdde 232
TomTom83 1:390d9808cdde 233 /* If pbuf is NULL then remote end has closed connection. */
TomTom83 1:390d9808cdde 234 if( p == NULL )
TomTom83 1:390d9808cdde 235 {
TomTom83 1:390d9808cdde 236 prvvMBPortReleaseClient( pxPCB );
TomTom83 1:390d9808cdde 237 return ERR_OK;
TomTom83 1:390d9808cdde 238 }
TomTom83 1:390d9808cdde 239
TomTom83 1:390d9808cdde 240 /* Acknowledge that we have received the data bytes. */
TomTom83 1:390d9808cdde 241 tcp_recved( pxPCB, p->len );
TomTom83 1:390d9808cdde 242
TomTom83 1:390d9808cdde 243 /* Check for internal buffer overflow. In case of an error drop the
TomTom83 1:390d9808cdde 244 * client. */
TomTom83 1:390d9808cdde 245 if( ( usTCPBufPos + p->len ) >= MB_TCP_BUF_SIZE )
TomTom83 1:390d9808cdde 246 {
TomTom83 1:390d9808cdde 247 prvvMBPortReleaseClient( pxPCB );
TomTom83 1:390d9808cdde 248 error = ERR_OK;
TomTom83 1:390d9808cdde 249 }
TomTom83 1:390d9808cdde 250 else
TomTom83 1:390d9808cdde 251 {
TomTom83 1:390d9808cdde 252 memcpy( &aucTCPBuf[usTCPBufPos], p->payload, p->len );
TomTom83 1:390d9808cdde 253 usTCPBufPos += p->len;
TomTom83 1:390d9808cdde 254
TomTom83 1:390d9808cdde 255 /* If we have received the MBAP header we can analyze it and calculate
TomTom83 1:390d9808cdde 256 * the number of bytes left to complete the current request. If complete
TomTom83 1:390d9808cdde 257 * notify the protocol stack.
TomTom83 1:390d9808cdde 258 */
TomTom83 1:390d9808cdde 259 if( usTCPBufPos >= MB_TCP_FUNC )
TomTom83 1:390d9808cdde 260 {
TomTom83 1:390d9808cdde 261 /* Length is a byte count of Modbus PDU (function code + data) and the
TomTom83 1:390d9808cdde 262 * unit identifier. */
TomTom83 1:390d9808cdde 263 usLength = aucTCPBuf[MB_TCP_LEN] << 8U;
TomTom83 1:390d9808cdde 264 usLength |= aucTCPBuf[MB_TCP_LEN + 1];
TomTom83 1:390d9808cdde 265
TomTom83 1:390d9808cdde 266 /* Is the frame already complete. */
TomTom83 1:390d9808cdde 267 if( usTCPBufPos < ( MB_TCP_UID + usLength ) )
TomTom83 1:390d9808cdde 268 {
TomTom83 1:390d9808cdde 269 }
TomTom83 1:390d9808cdde 270 else if( usTCPBufPos == ( MB_TCP_UID + usLength ) )
TomTom83 1:390d9808cdde 271 {
TomTom83 1:390d9808cdde 272 #ifdef MB_TCP_DEBUG
TomTom83 1:390d9808cdde 273 prvvMBTCPLogFrame( (UCHAR*)"MBTCP-RECV", &aucTCPBuf[0], usTCPBufPos );
TomTom83 1:390d9808cdde 274 #endif
TomTom83 1:390d9808cdde 275 ( void )xMBPortEventPost( EV_FRAME_RECEIVED );
TomTom83 1:390d9808cdde 276 }
TomTom83 1:390d9808cdde 277 else
TomTom83 1:390d9808cdde 278 {
TomTom83 1:390d9808cdde 279 #ifdef MB_TCP_DEBUG
TomTom83 1:390d9808cdde 280 vMBPortLog( MB_LOG_DEBUG, "MBTCP-ERROR",
TomTom83 1:390d9808cdde 281 "Received to many bytes! Droping client.\r\n" );
TomTom83 1:390d9808cdde 282 #endif
TomTom83 1:390d9808cdde 283 /* This should not happen. We can't deal with such a client and
TomTom83 1:390d9808cdde 284 * drop the connection for security reasons.
TomTom83 1:390d9808cdde 285 */
TomTom83 1:390d9808cdde 286 prvvMBPortReleaseClient( pxPCB );
TomTom83 1:390d9808cdde 287 }
TomTom83 1:390d9808cdde 288 }
TomTom83 1:390d9808cdde 289 }
TomTom83 1:390d9808cdde 290 pbuf_free( p );
TomTom83 1:390d9808cdde 291 return error;
TomTom83 1:390d9808cdde 292 }
TomTom83 1:390d9808cdde 293
TomTom83 1:390d9808cdde 294 BOOL
TomTom83 1:390d9808cdde 295 xMBTCPPortGetRequest( UCHAR ** ppucMBTCPFrame, USHORT * usTCPLength )
TomTom83 1:390d9808cdde 296 {
TomTom83 1:390d9808cdde 297 *ppucMBTCPFrame = &aucTCPBuf[0];
TomTom83 1:390d9808cdde 298 *usTCPLength = usTCPBufPos;
TomTom83 1:390d9808cdde 299
TomTom83 1:390d9808cdde 300 /* Reset the buffer. */
TomTom83 1:390d9808cdde 301 usTCPBufPos = 0;
TomTom83 1:390d9808cdde 302 return TRUE;
TomTom83 1:390d9808cdde 303 }
TomTom83 1:390d9808cdde 304
TomTom83 1:390d9808cdde 305 BOOL
TomTom83 1:390d9808cdde 306 xMBTCPPortSendResponse( const UCHAR * pucMBTCPFrame, USHORT usTCPLength )
TomTom83 1:390d9808cdde 307 {
TomTom83 1:390d9808cdde 308 BOOL bFrameSent = FALSE;
TomTom83 1:390d9808cdde 309
TomTom83 1:390d9808cdde 310 if( pxPCBClient )
TomTom83 1:390d9808cdde 311 {
TomTom83 1:390d9808cdde 312 /* Make sure we can send the packet. */
TomTom83 1:390d9808cdde 313 assert( tcp_sndbuf( pxPCBClient ) >= usTCPLength );
TomTom83 1:390d9808cdde 314
TomTom83 1:390d9808cdde 315 if( tcp_write( pxPCBClient, pucMBTCPFrame, ( u16_t ) usTCPLength, TCP_WRITE_FLAG_COPY ) == ERR_OK )
TomTom83 1:390d9808cdde 316 {
TomTom83 1:390d9808cdde 317 #ifdef MB_TCP_DEBUG
TomTom83 1:390d9808cdde 318 prvvMBTCPLogFrame( (UCHAR*)"MBTCP-SENT", &aucTCPBuf[0], usTCPLength );
TomTom83 1:390d9808cdde 319 #endif
TomTom83 1:390d9808cdde 320 /* Make sure data gets sent immediately. */
TomTom83 1:390d9808cdde 321 ( void )tcp_output( pxPCBClient );
TomTom83 1:390d9808cdde 322 bFrameSent = TRUE;
TomTom83 1:390d9808cdde 323 }
TomTom83 1:390d9808cdde 324 else
TomTom83 1:390d9808cdde 325 {
TomTom83 1:390d9808cdde 326 /* Drop the connection in case of an write error. */
TomTom83 1:390d9808cdde 327 prvvMBPortReleaseClient( pxPCBClient );
TomTom83 1:390d9808cdde 328 }
TomTom83 1:390d9808cdde 329 }
TomTom83 1:390d9808cdde 330 return bFrameSent;
TomTom83 1:390d9808cdde 331 }
TomTom83 1:390d9808cdde 332