LTP GCOV extension - code coverage report
Current view: directory - src/engine/tec - tec_tcp_handling.c
Test: min.info
Date: 2009-06-18 Instrumented lines: 279
Code covered: 72.0 % Executed lines: 201

       1                 : /*
       2                 :  * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
       3                 :  * and/or its subsidiary(-ies).
       4                 :  * Contact: Konrad Marek Zapalowicz
       5                 :  * Contact e-mail: DG.MIN-Support@nokia.com
       6                 :  * 
       7                 :  * This program is free software: you can redistribute it and/or modify it 
       8                 :  * under the terms of the GNU General Public License as published by the Free 
       9                 :  * Software Foundation, version 2 of the License. 
      10                 :  * 
      11                 :  * This program is distributed in the hope that it will be useful, but WITHOUT 
      12                 :  * ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or 
      13                 :  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General  Public License for
      14                 :  * more details. You should have received a copy of the GNU General Public 
      15                 :  * License along with this program. If not,  see 
      16                 :  * <http://www.gnu.org/licenses/>.
      17                 :  */
      18                 : 
      19                 : 
      20                 : /**
      21                 :  *  @file       tec_tcp_handling.c
      22                 :  *  @version    0.1
      23                 :  *  @brief      RCP handling routines for tcp based master slave
      24                 :  */
      25                 : 
      26                 : /* ------------------------------------------------------------------------- */
      27                 : /* INCLUDE FILES */
      28                 : #include <sys/types.h>
      29                 : #include <sys/socket.h>
      30                 : #include <sys/select.h>
      31                 : #include <netdb.h>
      32                 : #include <netinet/in.h>
      33                 : #include <arpa/inet.h>
      34                 : #include <pthread.h>
      35                 : 
      36                 : #include <tec.h>
      37                 : #include <tec_events.h>
      38                 : #include <min_common.h>
      39                 : #include <dllist.h>
      40                 : #include <min_parser.h>
      41                 : #include <min_logger.h>
      42                 : #include <tec_rcp_handling.h>
      43                 : 
      44                 : /* ------------------------------------------------------------------------- */
      45                 : /* EXTERNAL DATA STRUCTURES */
      46                 : /* None */
      47                 : 
      48                 : /* ------------------------------------------------------------------------- */
      49                 : /* EXTERNAL GLOBAL VARIABLES */
      50                 : extern DLList *ms_assoc;
      51                 : extern int slave_exit;
      52                 : /* ------------------------------------------------------------------------- */
      53                 : /* EXTERNAL FUNCTION PROTOTYPES */
      54                 : 
      55                 : /* ------------------------------------------------------------------------- */
      56                 : /* GLOBAL VARIABLES */
      57                 : int rcp_listen_socket = -1;
      58                 : pthread_mutex_t socket_write_mutex_ = PTHREAD_MUTEX_INITIALIZER;
      59                 : int current_slave_fd;
      60                 : /* ------------------------------------------------------------------------- */
      61                 : /* CONSTANTS */
      62                 : /* None */
      63                 : 
      64                 : /* ------------------------------------------------------------------------- */
      65                 : /* MACROS */
      66                 : /* None */
      67                 : 
      68                 : /* ------------------------------------------------------------------------- */
      69                 : /* LOCAL CONSTANTS AND MACROS */
      70                 : 
      71                 : /* ------------------------------------------------------------------------- */
      72                 : /* MODULE DATA STRUCTURES */
      73                 : /* None */
      74                 : 
      75                 : /* ------------------------------------------------------------------------- */
      76                 : /* LOCAL FUNCTION PROTOTYPES */
      77                 : /* ------------------------------------------------------------------------- */
      78                 : /** Goes through the list of slaves and sets sockets that are available
      79                 :  *  for reading or writing to the fd sets
      80                 :  *  @param rd set of read sockets
      81                 :  *  @param wr set of write sockets
      82                 :  *  @param nfds highest fd in sets before calling this func
      83                 :  *  @return the value of highest fd in set
      84                 :  */
      85                 : LOCAL int set_active_rcp_sockets (fd_set *rd, fd_set *wr, int nfds);
      86                 : /* ------------------------------------------------------------------------- */
      87                 : /** Read/write sockets  
      88                 :  *  @param rd set of read sockets
      89                 :  *  @param wr set of write sockets
      90                 :  */
      91                 : LOCAL void rw_rcp_sockets (fd_set *rd, fd_set *rw);
      92                 : /* ------------------------------------------------------------------------- */
      93                 : /** Reads the socket bound to the slave_info
      94                 :  *  @param slave_info the slave with a socket available for reading
      95                 :  */
      96                 : LOCAL void socket_read_rcp (slave_info *slave);
      97                 : /* ------------------------------------------------------------------------- */
      98                 : /** Writes to socket bound to slave_info
      99                 :  *  @param slave_info the slave with a socket available for writing
     100                 :  */
     101                 : LOCAL void socket_write_rcp (slave_info *slave);
     102                 : /* ------------------------------------------------------------------------- */
     103                 : /** Finds a slave with fd
     104                 :  *  @param fd search key
     105                 :  *  @param itp out used to pass also the DLListIterator to caller
     106                 :  *  @return slave_info if found, INITPTR if not
     107                 :  */
     108                 : LOCAL slave_info *find_slave_by_fd (int fd, DLListIterator *itp);
     109                 : /* ------------------------------------------------------------------------- */
     110                 : /** Searches for master (a "special" slave)
     111                 :  *  @return slave_info if found, INITPTR if not
     112                 :  */
     113                 : LOCAL slave_info *find_master ();
     114                 : /* ------------------------------------------------------------------------- */
     115                 : /** Frees the tcp type slave - closes slave socket, marks the slave free
     116                 :  *  @param slave slave to be freed
     117                 :  */
     118                 : LOCAL void free_tcp_slave (slave_info *slave);
     119                 : /* ------------------------------------------------------------------------- */
     120                 : /** Splits RCP's adress string fields into two ints.
     121                 :  * @param hex [in] string to be split, has to be 8 characters, otherwise
     122                 :  *  function fails
     123                 :  * @param dev_id [out] pointer to int that will hold device id
     124                 :  * @param case_id [out] pointer to int that will hold case id
     125                 :  * @return result of operation, 0 if ok
     126                 :  */
     127                 : LOCAL int splithex (char *hex, int *dev_id, int *case_id);
     128                 : 
     129                 : /* ------------------------------------------------------------------------- */
     130                 : /* FORWARD DECLARATIONS */
     131                 : /* None */
     132                 : 
     133                 : /* ==================== LOCAL FUNCTIONS ==================================== */
     134                 : /* ------------------------------------------------------------------------- */
     135                 : LOCAL int set_active_rcp_sockets (fd_set *rd, fd_set *wr, int nfds)
     136         2191005 : {
     137                 :         DLListIterator it;
     138                 :         slave_info *slave;
     139                 :         
     140         6573026 :         for (it = dl_list_head (ms_assoc); it != INITPTR;
     141         2191016 :              it = dl_list_next (it)) {
     142         2191016 :                 slave = dl_list_data (it);
     143         2191016 :                 if (slave->fd_ != 0 && slave->fd_ != -1) {
     144         2189815 :                         FD_SET (slave->fd_, rd);
     145         2189815 :                         FD_SET (slave->fd_, wr);
     146         2189815 :                         nfds = MAX (nfds, slave->fd_);
     147                 :                 }
     148                 :         }
     149                 :        
     150         2191005 :         return nfds;
     151                 : }
     152                 : /* ------------------------------------------------------------------------- */
     153                 : LOCAL void rw_rcp_sockets (fd_set *rd, fd_set *wr)
     154         2190990 : {
     155                 :         DLListIterator it;
     156                 :         slave_info *slave;
     157                 :         
     158         6572993 :         for (it = dl_list_head (ms_assoc); it != INITPTR;
     159         2191013 :              it = dl_list_next (it)) {
     160         2191013 :                 slave = dl_list_data (it);
     161         2191013 :                 if (slave->fd_ > 0) {
     162         2189816 :                         if (FD_ISSET (slave->fd_, rd))
     163               5 :                                 socket_read_rcp (slave);
     164         2189816 :                         if (slave->fd_ > 0 && FD_ISSET (slave->fd_, wr))
     165         2189814 :                                 socket_write_rcp (slave);
     166                 :                 }
     167                 :         }
     168                 :        
     169                 : 
     170                 :         return;
     171                 : }
     172                 : /* ------------------------------------------------------------------------- */
     173                 : LOCAL void free_tcp_slave (slave_info *slave)
     174               0 : {
     175                 :         slave_info *master;
     176                 :         DLListIterator it;
     177               0 :         if (!strcmp (tx_share_buf(slave->slave_type_), "master")) {
     178               0 :                 master = find_slave_by_fd (slave->fd_, &it);
     179               0 :                 close (master->fd_);
     180               0 :                 tx_destroy (&master->slave_type_);
     181               0 :                 tx_destroy (&master->slave_name_);
     182               0 :                 dl_list_free (&master->write_queue_);
     183               0 :                 dl_list_remove_it (it);
     184               0 :                 DELETE (master);
     185               0 :                 slave_exit = 1;
     186               0 :                 return;
     187                 :         } 
     188                 : 
     189               0 :         close (slave->fd_);
     190               0 :         slave->fd_ = -1;
     191               0 :         slave->status_ = SLAVE_STAT_FREE;
     192               0 :         slave->slave_id_ = 0;
     193               0 :         tx_destroy (&slave->slave_name_);
     194               0 :         return;
     195                 : }
     196                 : /* ------------------------------------------------------------------------- */
     197                 : LOCAL void socket_read_rcp (slave_info *slave)
     198               5 : {
     199                 :         int bytes_read;
     200                 :         char *buff, len_buff[2];
     201                 :         unsigned int len;
     202                 :         
     203               5 :         bytes_read = read (slave->fd_, &len_buff, 2);
     204               5 :         if (bytes_read != 2) {
     205               0 :                 MIN_WARN ("can't read even 2 bytes from socket");
     206               0 :                 free_tcp_slave (slave);
     207               0 :                 return;
     208                 :         }
     209               5 :         len = len_buff [1] << 8  | len_buff [0];
     210               5 :         MIN_INFO ("Message from RCP socket of len %d", len);
     211               5 :         buff = NEW2 (char, len + 1);
     212               5 :         bytes_read = read (slave->fd_, buff, len);
     213               5 :         if (bytes_read != len) {
     214               0 :                 MIN_WARN ("failed to read the whole message");
     215               0 :                 free_tcp_slave (slave);
     216               0 :                 return;
     217                 :         }
     218                 : 
     219               5 :         buff [len] = '\0';
     220               5 :         current_slave_fd = slave->fd_; 
     221               5 :         tec_extif_message_received (buff, len);
     222                 : 
     223               5 :         DELETE (buff);
     224                 : 
     225               5 :         return;
     226                 : 
     227                 : }
     228                 : /* ------------------------------------------------------------------------- */
     229                 : LOCAL void socket_write_rcp (slave_info *slave)
     230         2189814 : {
     231                 :         Text *tx;
     232                 :         DLListIterator it;
     233                 :         int ret;
     234                 :         char len_buff[5];
     235                 : 
     236         2189814 :         if (slave->write_queue_ == NULL || slave->write_queue_ == INITPTR) {
     237               0 :                 MIN_WARN ("write queue does not exist");
     238               0 :                 return;
     239                 :         }
     240                 : 
     241         2189814 :         pthread_mutex_lock (&socket_write_mutex_);
     242                 : 
     243         2189814 :         it = dl_list_head (slave->write_queue_);
     244         2189814 :         if (it == DLListNULLIterator) {
     245         2189811 :                 pthread_mutex_unlock (&socket_write_mutex_);
     246                 : 
     247         2189811 :                 return;
     248                 :         }
     249                 :         
     250               3 :         tx = dl_list_data (it);
     251                 : 
     252               3 :         len_buff[0] = strlen (tx_share_buf(tx));
     253               3 :         len_buff[1] = strlen (tx_share_buf(tx)) >> 8;
     254                 :         
     255               3 :         ret = write (slave->fd_, &len_buff, 2);
     256                 : 
     257               3 :         MIN_DEBUG ("SENDING TO EXTIF :%s", tx_share_buf (tx));
     258               3 :         ret = write (slave->fd_, tx_share_buf (tx), strlen (tx_share_buf (tx)));
     259                 : 
     260               3 :         dl_list_remove_it (it);
     261               3 :         tx_destroy (&tx);
     262               3 :         pthread_mutex_unlock (&socket_write_mutex_);
     263                 : 
     264               3 :         return;
     265                 :         
     266                 : }
     267                 : /* ------------------------------------------------------------------------- */
     268                 : LOCAL slave_info *find_slave_by_fd (int fd, DLListIterator *itp)
     269               7 : {
     270                 :        DLListIterator it;
     271                 :        slave_info *ips;
     272                 :  
     273               7 :        *itp = INITPTR;
     274                 : 
     275              14 :        for (it = dl_list_head (ms_assoc); it != INITPTR;
     276               0 :             it = dl_list_next (it)) {
     277               7 :                ips = dl_list_data (it);
     278               7 :                if (ips->fd_ == fd)  {
     279               7 :                        *itp = it;
     280               7 :                        return ips;
     281                 :                }
     282                 :        }
     283                 :        
     284               0 :        return INITPTR;
     285                 : }
     286                 : /* ------------------------------------------------------------------------- */
     287                 : LOCAL slave_info *find_master ()
     288               0 : {
     289                 :        DLListIterator it;
     290                 :        slave_info *ips;
     291                 :  
     292                 : 
     293               0 :        for (it = dl_list_head (ms_assoc); it != INITPTR;
     294               0 :             it = dl_list_next (it)) {
     295               0 :                ips = dl_list_data (it);
     296               0 :                if (!strcmp (tx_share_buf (ips->slave_type_), "master"))  {
     297               0 :                        return ips;
     298                 :                }
     299                 :        }
     300                 :        
     301               0 :        return INITPTR;
     302                 : }
     303                 : /* ------------------------------------------------------------------------- */
     304                 : LOCAL int splithex (char *hex, int *dev_id, int *case_id)
     305               4 : {
     306                 :         char            dev_id_c[5];
     307                 :         char            case_id_c[5];
     308                 :         char           *endptr;
     309                 : 
     310               4 :         if (strlen (hex) != 8) {
     311               0 :                 return -1;
     312                 :         }
     313                 : 
     314               4 :         snprintf (dev_id_c, 5, "%s", hex);
     315               4 :         snprintf (case_id_c, 5, "%s", hex + 4);
     316               4 :         *dev_id = strtol (dev_id_c, &endptr, 16);
     317               4 :         *case_id = strtol (case_id_c, &endptr, 16);
     318                 : 
     319               4 :         return 0;
     320                 : }
     321                 : /* ------------------------------------------------------------------------- */
     322                 : 
     323                 : /* ------------------------------------------------------------------------- */
     324                 : /* ======================== FUNCTIONS ====================================== */
     325                 : /* ------------------------------------------------------------------------- */
     326                 : /** Handles socket polling thread
     327                 :  *  @return NULL
     328                 :  */
     329                 : void *ec_poll_sockets (void *arg)
     330              15 : {
     331                 :         fd_set rd, wr, er;
     332              15 :         int nfds = 0;
     333                 :         struct timeval tv;
     334                 :         int ret;
     335                 : 
     336                 :         
     337                 :         while (1) {
     338         2191005 :                 FD_ZERO (&rd);
     339         2191005 :                 FD_ZERO (&wr);
     340         2191005 :                 FD_ZERO (&er);
     341         2191005 :                 nfds = set_active_rcp_sockets (&rd, &wr, nfds);
     342                 :                 
     343         2191005 :                 tv.tv_sec = 0;
     344         2191005 :                 tv.tv_usec = 100000;
     345         2191005 :                 ret = select (nfds + 1, &rd, &wr, &er, &tv);
     346                 :                 
     347         2190990 :                 rw_rcp_sockets (&rd, &wr);
     348         2190990 :         }
     349                 : 
     350                 :         return NULL;
     351                 : }
     352                 : 
     353                 : /* ------------------------------------------------------------------------- */
     354                 : /** Build rcp message and adds it to the write queue of slave
     355                 :  *  @param cmd command e.g. "reserve"
     356                 :  *  @param sender RCP sender identifier
     357                 :  *  @param rcvr RCP receiver identifier
     358                 :  *  @param msg the rest of message
     359                 :  *  @param fd the socket of the destination
     360                 :  */
     361                 : void socket_send_rcp (char *cmd, char *sender, char *rcvr, char* msg, int fd)
     362               3 : {
     363                 :         Text *tx;
     364                 :         slave_info *entry;
     365                 :         DLListIterator it;
     366                 : 
     367               3 :         MIN_DEBUG ("cmd:%s sender:%s rcvr:%s msg:%s fd:%d",
     368                 :                    cmd, sender, rcvr, msg, fd);
     369                 : 
     370               3 :         tx = tx_create (cmd);
     371               3 :         tx_c_append (tx, " ");
     372               3 :         tx_c_append (tx, sender);
     373               3 :         tx_c_append (tx, " ");
     374               3 :         tx_c_append (tx, rcvr);
     375               3 :         tx_c_append (tx, " ");
     376               3 :         tx_c_append (tx, msg);
     377                 : 
     378               3 :         if (fd == 0 && !strcmp (rcvr, "deadbeef"))
     379               0 :                 entry = find_master ();
     380                 :         else
     381               3 :                 entry = find_slave_by_fd (fd, &it);
     382                 :         
     383               3 :         if (entry == INITPTR) {
     384               0 :                 MIN_WARN ("No entry found for socket %d", fd);
     385               0 :                 return;
     386                 :         }
     387               3 :         pthread_mutex_lock (&socket_write_mutex_);
     388                 : 
     389               3 :         dl_list_add (entry->write_queue_, tx);
     390                 : 
     391               3 :         pthread_mutex_unlock (&socket_write_mutex_);
     392                 : 
     393                 : }
     394                 : 
     395                 : /* ------------------------------------------------------------------------- */
     396                 : /** Tries to allocate slave entry for IP communication
     397                 :  *  @param he host address information
     398                 :  *  @param slavetype type of the slave e.g. "phone"
     399                 :  *  @return 0 on success, 1 on error
     400                 :  */
     401                 : int allocate_ip_slave (char *slavetype, char *slavename, pid_t pid)
     402               1 : {
     403                 :        slave_info *slave;
     404                 :        static int slave_id = 0;
     405                 :        DLListIterator it;
     406               1 :        int found = 0, sfd;
     407                 :        struct addrinfo *rp;
     408                 : 
     409               1 :        if (ms_assoc == INITPTR)
     410               0 :                return -1;
     411                 :        
     412               2 :        for (it = dl_list_head (ms_assoc); it != INITPTR;
     413               0 :             it = dl_list_next (it)) {
     414               1 :                slave = dl_list_data (it);
     415               1 :                if (!strcmp (tx_share_buf (slave->slave_type_), slavetype) &&
     416                 :                    slave->status_ == SLAVE_STAT_FREE) {
     417               1 :                        found = 1;
     418               1 :                        slave->slave_name_ = tx_create (slavename);
     419               1 :                        break;
     420                 :                }
     421                 :        }
     422                 :        
     423               1 :        if (found == 0) {
     424               0 :                MIN_WARN ("no slave of type %s found from ip slave pool");
     425               0 :                return -1;
     426                 :        }
     427                 : 
     428               1 :        for (rp = slave->addrinfo_; rp != NULL; rp = rp->ai_next) {
     429               1 :                sfd = socket(rp->ai_family, rp->ai_socktype,
     430                 :                             rp->ai_protocol);
     431               1 :                if (sfd == -1)
     432               0 :                        continue;
     433                 : 
     434               1 :                if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
     435               1 :                        break;                  
     436                 : 
     437               0 :                close(sfd);
     438                 :        }
     439                 : 
     440               1 :        if (rp == NULL) {               
     441               0 :                MIN_WARN ("Could not connect %s", strerror(errno));
     442               0 :                return -1;
     443                 :        }
     444                 :        
     445               1 :        if (slave_id >= 0xffff) {
     446               0 :                MIN_WARN ("Slave id wraparound");
     447               0 :                slave_id = 1;
     448                 :        } else
     449               1 :                slave_id ++;
     450                 :        
     451               1 :        slave->fd_ = sfd;
     452               1 :        slave->slave_id_ = slave_id;
     453               1 :        slave->status_ = SLAVE_STAT_RESERVED;
     454               1 :        slave->pid_ = pid;
     455                 : 
     456               1 :        return 0;
     457                 : }
     458                 : 
     459                 : /* ------------------------------------------------------------------------- */
     460                 : /** Creates a new master entry
     461                 :  * param socket the socket of the master
     462                 :  */
     463                 : void new_tcp_master (int socket)
     464               0 : {
     465                 :         slave_info *master;
     466                 :         
     467               0 :         master = NEW (slave_info);
     468               0 :         master->slave_name_ = tx_create ("deadbeef");
     469               0 :         master->slave_type_ = tx_create ("master");
     470               0 :         master->fd_ = socket;
     471               0 :         master->write_queue_ = dl_list_create ();
     472               0 :         master->status_ = SLAVE_STAT_RESERVED;
     473                 : 
     474               0 :         dl_list_add (ms_assoc, master);
     475                 : 
     476                 :         return;
     477                 : }
     478                 : 
     479                 : /* ------------------------------------------------------------------------- */
     480                 : /** Function to close slave 
     481                 :  * @param slave the slave_info struck
     482                 :  */
     483               1 : void tcp_slave_close (slave_info *slave) {
     484               1 :         close (slave->fd_);
     485               1 :         slave->fd_ = -1;
     486               1 :         slave->status_ = SLAVE_STAT_FREE ;
     487               1 :         tx_destroy (&slave->slave_name_);
     488               1 : }
     489                 : 
     490                 : /* ------------------------------------------------------------------------- */
     491                 : /**Function handles "response" message coming from external controller over tcp
     492                 :  * @param extif_message pointer to item parser. It is assumed that 
     493                 :  * mip_get_string was  executed once for this parser to get first "word"
     494                 :  * @return result of operation, 0 if ok.
     495                 :  */
     496                 : int tcp_msg_handle_response (MinItemParser * extif_message)
     497               4 : {
     498               4 :         char           *command = INITPTR;
     499               4 :         char           *param1 = NULL;
     500               4 :         char           *srcid = INITPTR;
     501               4 :         char           *destid = INITPTR;
     502               4 :         int             result = 666;
     503               4 :         int             retval = 666;
     504               4 :         int             slave_id = 0;
     505               4 :         int             case_id = 0;
     506                 :         MsgBuffer       ipc_message;
     507               4 :         slave_info     *slave_entry = INITPTR;
     508                 :         DLListIterator  slave_entry_item;
     509                 : 
     510               4 :         mip_get_next_string (extif_message, &srcid);
     511                 : 
     512               4 :         mip_get_next_string (extif_message, &destid);
     513                 : 
     514               4 :         mip_get_next_string (extif_message, &command);
     515                 :         
     516               4 :         slave_entry = find_slave_by_fd (current_slave_fd, &slave_entry_item);
     517               4 :         if (slave_entry == INITPTR) {
     518               0 :                 MIN_FATAL ("no slave found bound to fd %d!",
     519                 :                            current_slave_fd);
     520                 :         }
     521                 : 
     522               4 :         current_slave_fd = -1;
     523                 : 
     524               4 :         if (strcasecmp (command, "reserve") == 0) {
     525               1 :                 mip_get_next_int (extif_message, &result);
     526                 :                 
     527                 :                 /*it seems that result was not send, assume success */
     528               1 :                 splithex (srcid, &slave_id, &case_id);
     529               1 :                 slave_entry->slave_id_ = slave_id;
     530               1 :                 if (retval == -1)
     531               0 :                         result = 0;
     532               1 :                 slave_entry->status_ = SLAVE_STAT_RESERVED;
     533                 : 
     534               1 :                 ipc_message.sender_ = ec_settings.engine_pid_;
     535               1 :                 ipc_message.receiver_ = slave_entry->pid_;
     536               1 :                 ipc_message.type_ = MSG_EXTIF;
     537               1 :                 ipc_message.special_ = 0;
     538               1 :                 ipc_message.extif_msg_type_ = EResponseSlave;
     539               1 :                 ipc_message.param_ = result;
     540               1 :                 MIN_DEBUG ("ipc sending with result %d", result);
     541               1 :                 mq_send_message (mq_id, &ipc_message);
     542               1 :                 retval = 0;
     543               3 :         } else if (strcasecmp (command, "release") == 0) {
     544               1 :                 retval =
     545                 :                     mip_get_next_tagged_int (extif_message, "result=", &result);
     546               1 :                 if (retval == -1)
     547               1 :                         mip_get_next_int (extif_message, &result);
     548                 :                 /*result was not tagged int */
     549               1 :                 if (retval == -1)
     550               1 :                         result = 0;
     551                 :                 /*it seems that result was not send, assume success */
     552               1 :                 ipc_message.sender_ = ec_settings.engine_pid_;
     553               1 :                 ipc_message.receiver_ = slave_entry->pid_;
     554               1 :                 ipc_message.type_ = MSG_EXTIF;
     555               1 :                 ipc_message.param_ = result;
     556               1 :                 ipc_message.special_ = 0;
     557               1 :                 ipc_message.extif_msg_type_ = EResponseSlave;
     558               1 :                 MIN_DEBUG ("ipc sending with result %d", result);
     559               1 :                 mq_send_message (mq_id, &ipc_message);
     560                 :                 /*slave released, remove it from ms_assoc */
     561               1 :                 splithex (srcid, &slave_id, &case_id);
     562               1 :                 MIN_DEBUG ("slave_entry = %x, run count = %d",
     563                 :                            slave_entry, slave_entry->run_cnt_);
     564               1 :                 if (slave_entry->run_cnt_ == 0) {
     565                 :                         /* we have a result - can close */
     566               1 :                         tcp_slave_close (slave_entry);
     567                 :                 } else
     568               0 :                         slave_entry->status_ &= 0xe;
     569                 :                 
     570               1 :                 retval = 0;
     571               2 :         } else if (strcasecmp (command, "remote") == 0) {
     572               2 :                 mip_get_next_string (extif_message, &command);
     573               2 :                 if (strcasecmp (command, "run") == 0) {
     574               2 :                         splithex (srcid, &slave_id, &case_id);
     575                 :                         /*translate received caseid into proper 
     576                 :                         number that can be stored in scripter*/
     577               2 :                         case_id = (slave_id<<16) + case_id;
     578               2 :                         mip_get_next_string (extif_message, &param1);
     579               2 :                         if (strcasecmp (param1, "started") == 0) {
     580               1 :                                 ipc_message.sender_ = ec_settings.engine_pid_;
     581               1 :                                 ipc_message.receiver_ = slave_entry->pid_;
     582               1 :                                 ipc_message.type_ = MSG_EXTIF;
     583               1 :                                 ipc_message.special_ = case_id;
     584               1 :                                 ipc_message.param_ = 0;
     585               1 :                                 ipc_message.extif_msg_type_ = EResponseSlave;
     586               1 :                                 MIN_DEBUG ("ipc sending with result 0");
     587               1 :                                 mq_send_message (mq_id, &ipc_message);
     588               1 :                                 retval = 0;
     589               1 :                         } else if (strcasecmp (param1, "ready") == 0) {
     590               1 :                                 mip_get_int (extif_message, "result=", &result);
     591               1 :                                 ipc_message.sender_ = ec_settings.engine_pid_;
     592               1 :                                 ipc_message.receiver_ = slave_entry->pid_;
     593               1 :                                 ipc_message.type_ = MSG_EXTIF;
     594               1 :                                 ipc_message.special_ = case_id;
     595               1 :                                 ipc_message.param_ = result;
     596               1 :                                 ipc_message.extif_msg_type_ =
     597                 :                                     ERemoteSlaveResponse;
     598               1 :                                 MIN_DEBUG ("ipc sending with result %d",
     599                 :                                              result);
     600               1 :                                 mq_send_message (mq_id, &ipc_message);
     601               1 :                                 retval = 0;
     602               2 :                                 if (slave_entry != INITPTR && 
     603                 :                                     slave_entry->status_ 
     604                 :                                     & SLAVE_STAT_RESERVED) {
     605               1 :                                         slave_entry->run_cnt_ -= 1; 
     606                 :                                         
     607                 :                                 } else {
     608                 :                                         /* we have are free - can close */
     609               0 :                                         tcp_slave_close (slave_entry);
     610                 :                                 }
     611               0 :                         } else if (strcasecmp (param1, "error") == 0) {
     612               0 :                                 mip_get_int (extif_message, "result=", &result);
     613               0 :                                 ipc_message.sender_ = ec_settings.engine_pid_;
     614               0 :                                 ipc_message.receiver_ = slave_entry->pid_;
     615               0 :                                 ipc_message.type_ = MSG_EXTIF;
     616               0 :                                 ipc_message.special_ = case_id;
     617               0 :                                 ipc_message.param_ = result;
     618               0 :                                 ipc_message.extif_msg_type_ = EResponseSlave;
     619               0 :                                 MIN_DEBUG ("ipc sending with result %d",
     620                 :                                              result);
     621               0 :                                 mq_send_message (mq_id, &ipc_message);
     622               0 :                                 retval = 0;
     623               0 :                                 if (slave_entry != INITPTR &&
     624                 :                                     slave_entry->status_ & 
     625                 :                                     SLAVE_STAT_RESERVED) {
     626               0 :                                         slave_entry->run_cnt_ -= 1; 
     627                 : 
     628                 :                                 } else {
     629                 :                                         /* we have are free - can close */
     630               0 :                                         tcp_slave_close (slave_entry);
     631                 :                                 }
     632                 : 
     633                 :                         }
     634               0 :                 } else if (strcasecmp (command, "request") == 0) {
     635               0 :                         retval =
     636                 :                             handle_remote_event_request_resp (extif_message);
     637               0 :                 } else if (strcasecmp (command, "release") == 0)
     638               0 :                         retval = 0;
     639                 :         }
     640               4 :         DELETE (command);
     641               4 :         DELETE (param1);
     642               4 :         DELETE (srcid);
     643               4 :         DELETE (destid);
     644                 : 
     645               4 :         return retval;
     646                 : }
     647                 : 
     648                 : /* ------------------------------------------------------------------------- */
     649                 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
     650                 : /* None */
     651                 : 
     652                 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
     653                 : /* None */
     654                 : 
     655                 : /* ------------------------------------------------------------------------- */
     656                 : /* End of file */

Generated by: LTP GCOV extension version 1.6