X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Frmr%2Fsi%2Fsrc%2Fsi95%2Fsircv.c;fp=src%2Frmr%2Fsi%2Fsrc%2Fsi95%2Fsircv.c;h=2202629501f3185bd591b41212f9068e8d830c06;hb=ec88d3c0563eeb6ae5f73427edb0b3c4d7acf299;hp=0000000000000000000000000000000000000000;hpb=77406e61f2158f5b88b7a9f6e3e86d8f62c8f71a;p=ric-plt%2Flib%2Frmr.git diff --git a/src/rmr/si/src/si95/sircv.c b/src/rmr/si/src/si95/sircv.c new file mode 100644 index 0000000..2202629 --- /dev/null +++ b/src/rmr/si/src/si95/sircv.c @@ -0,0 +1,139 @@ +// vim: noet sw=4 ts=4: +/* +================================================================================== + Copyright (c) 2020 Nokia + Copyright (c) 2020 AT&T Intellectual Property. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +================================================================================== +*/ + +/* X +***************************************************************************** +* +* Mnemonic: SIrcv +* Abstract: This routine allows the user program to receive data on a +* session without using the callback structure of the library. +* It is the caller's responsibility to provide a buffer large +* enough to handle the received data. +* Parms: gptr - The SIHANDLE that the user received on init call +* sid - The session id that the user wants to check +* buf - Pointer to buffer to receive data in +* abuf - Pointer to buffer to return address of UDP sender in (!null) +* buflen-Length of the receive buffer +* delay- Value to pass to poll (time out) -1 == block until data +* Returns: SI_ERROR - (SIerrno will contain reason) if failure, else the +* number of bytes read. If the number read is 0 SIerrno will indicate +* why: time out exceeded, signal received. +* Date: 26 March 1995 +* Author: E. Scott Daniels +* Mods: 26 Mar 20001 - Changed to support UDP reads +* +****************************************************************************** +*/ +#include "sisetup.h" // get start up stuff +#include "sitransport.h" + +extern int SIrcv( struct ginfo_blk *gptr, int sid, char *buf, int buflen, char *abuf, int delay ) { + //extern int sigflags; // signal flags + int status = SI_ERROR; // assume the worst to return to caller + struct tp_blk *tpptr; // pointer to transport provider info + int flags = 0; // receive flags + int remainder; // # of bytes remaining after rcv if more + fd_set readfds; // special set of read fds for this call + fd_set execpfds; // special set of read fds for this call + struct timeval *tptr = NULL; // time info for select call + struct timeval time; + struct sockaddr *uaddr; // pointer to udp address + char *acbuf; // pointer to converted address + int addrlen; + + gptr->sierr = SI_ERR_HANDLE; // set errno before we fail + if( gptr->magicnum != MAGICNUM ) // if not a valid ginfo block + return SI_ERROR; + + gptr->sierr = SI_ERR_SESSID; // set errno before we fail + for( tpptr = gptr->tplist; tpptr != NULL && tpptr->fd != sid; + tpptr = tpptr->next ); // find transport block + if( tpptr == NULL ) + return SI_ERROR; // signal bad block + + uaddr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) ); + addrlen = sizeof( *uaddr ); + + gptr->sierr = SI_ERR_SHUTD; // set errno before we fail + if( ! (gptr->flags & GIF_SHUTDOWN) ) + { // if not in shutdown and no signal flags + FD_ZERO( &readfds ); // clear select info + FD_SET( tpptr->fd, &readfds ); // set to check read status + + FD_ZERO( &execpfds ); // clear select info + FD_SET( tpptr->fd, &execpfds ); // set to check read status + + if( delay >= 0 ) // user asked for a fininte time limit + { + tptr = &time; // point at the local struct + tptr->tv_sec = 0; // setup time for select call + tptr->tv_usec = delay; + } + + gptr->sierr = SI_ERR_TP; + if( (select( tpptr->fd + 1, &readfds, NULL, &execpfds, tptr ) < 0 ) ) + gptr->flags |= GIF_SHUTDOWN; // we must shut on error or signal + else + { // poll was successful - see if data ? + gptr->sierr = SI_ERR_TIMEOUT; + if( FD_ISSET( tpptr->fd, &execpfds ) ) // session error? + { + SIterm( gptr, tpptr ); // clean up our end of things + gptr->sierr = SI_ERR_SESSID; // set errno before we fail + } + else + { + if( (FD_ISSET( tpptr->fd, &readfds )) ) + { // process data if no signal + gptr->sierr = SI_ERR_TP; + if( tpptr->type == SOCK_DGRAM ) // raw data received + { + status = RECVFROM( sid, buf, buflen, 0, uaddr, &addrlen ); + if( abuf ) + { + SIaddress( uaddr, (void **) &acbuf, AC_TODOT ); // address returns pointer to buf now rather than filling + strcpy( abuf, acbuf ); // must be back compat with old versions + free( acbuf ); + } + if( status < 0 ) // session terminated? + SIterm( gptr, tpptr ); // so close our end + } + else // cooked data received + { + status = RECV( sid, buf, buflen, 0 ); // read data into user buf + if( status < 0 ) // session terminated? + SIterm( gptr, tpptr ); // so close our end + } + } // end event was received + else // no event was received + status = 0; // status is just ok + } // end else - not in shutdown mode after poll + } // end else pole was successful + } // end if not already signal shutdown + + if( gptr->flags & GIF_SHUTDOWN && gptr->tplist != NULL ) + { // shutdown received but sessions not cleaned up + SIshutdown( gptr ); + status = SI_ERROR; // indicate failure on return + } // end if shut but not clean + + free( uaddr ); + return status; // send back the status +} // SIrcv