LTP GCOV extension - code coverage report
Current view: directory - src/engine/tec - tec_rcp_handling.c
Test: min.info
Date: 2009-06-18 Instrumented lines: 678
Code covered: 55.9 % Executed lines: 379

       1                 : /*
       2                 :  * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
       3                 :  * and/or its subsidiary(-ies).
       4                 :  * Contact: Robert Galkowski
       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_rcp_handling.c
      22                 :  *  @version    0.1
      23                 :  *  @brief      This file contains implementation of min RCP message handling
      24                 :  */
      25                 : 
      26                 : /* ------------------------------------------------------------------------- */
      27                 : /* INCLUDE FILES */
      28                 : #include <tec.h>
      29                 : #include <tec_events.h>
      30                 : #include <data_api.h>
      31                 : #include <string.h>
      32                 : #include <scripter_keyword.h>
      33                 : #include <mintfwif.h>
      34                 : #include <min_engine_api.h>
      35                 : #ifndef MIN_EXTIF
      36                 : #include <sys/socket.h>
      37                 : #include <netinet/in.h>
      38                 : #include <arpa/inet.h>
      39                 : #include <tec_tcp_handling.h>
      40                 : #endif
      41                 : 
      42                 : /* ------------------------------------------------------------------------- */
      43                 : /* EXTERNAL DATA STRUCTURES */
      44                 : #ifdef MIN_EXTIF
      45                 : extern tfwif_callbacks_s tfwif_callbacks;
      46                 : #endif 
      47                 : extern eapiIn_t *in;
      48                 : 
      49                 : /* ------------------------------------------------------------------------- */
      50                 : /* EXTERNAL GLOBAL VARIABLES */
      51                 : extern pthread_mutex_t tec_mutex_;
      52                 : 
      53                 : /* ------------------------------------------------------------------------- */
      54                 : /* EXTERNAL FUNCTION PROTOTYPES */
      55                 : /* ------------------------------------------------------------------------- */
      56                 : extern char    *strcasestr (__const char *__haystack, __const char *__needle);
      57                 : 
      58                 : /* GLOBAL VARIABLES */
      59                 : /** List containing association data for master - slave system
      60                 : (slave_info structures)*/
      61                 : DLList         *ms_assoc;
      62                 : DLList         *EXTIF_received_data;
      63                 : #ifdef MIN_EXTIF
      64                 : min_case_complete_func original_complete_callback;
      65                 : #endif
      66                 : TSBool          ok_to_break;    /*flag stating if it is ok to revert back to
      67                 :                                  * normal external controller communication 
      68                 :                                  * instead of slave mode */
      69                 : /* ------------------------------------------------------------------------- */
      70                 : /* CONSTANTS */
      71                 : /* None */
      72                 : 
      73                 : /* ------------------------------------------------------------------------- */
      74                 : /* MACROS */
      75                 : /* None */
      76                 : 
      77                 : /* ------------------------------------------------------------------------- */
      78                 : /* LOCAL GLOBAL VARIABLES */
      79                 : /* None */
      80                 : 
      81                 : /* ------------------------------------------------------------------------- */
      82                 : /* LOCAL CONSTANTS AND MACROS */
      83                 : /* None */
      84                 : 
      85                 : /* ------------------------------------------------------------------------- */
      86                 : /* MODULE DATA STRUCTURES */
      87                 : /* None */
      88                 : /* ------------------------------------------------------------------------- */
      89                 : /* LOCAL FUNCTION PROTOTYPES */
      90                 : /* ------------------------------------------------------------------------- */
      91                 : LOCAL int       min_if_dispatch_extif_msg (MinItemParser * extif_message);
      92                 : /* ------------------------------------------------------------------------- */
      93                 : LOCAL int       extif_msg_handle_reserve (MinItemParser * extif_message);
      94                 : /* ------------------------------------------------------------------------- */
      95                 : LOCAL int       extif_msg_handle_release (MinItemParser * extif_message);
      96                 : /* ------------------------------------------------------------------------- */
      97                 : #ifdef MIN_EXTIF
      98                 : LOCAL int       extif_msg_handle_response (MinItemParser * extif_message);
      99                 : #endif
     100                 : /* ------------------------------------------------------------------------- */
     101                 : LOCAL int       extif_msg_handle_command (MinItemParser * extif_message);
     102                 : /* ------------------------------------------------------------------------- */
     103                 : LOCAL int       handle_remote_run (MinItemParser * extif_message);
     104                 : /* ------------------------------------------------------------------------- */
     105                 : LOCAL int       handle_remote_pause (MinItemParser * extif_message,
     106                 :                                      int case_id);
     107                 : /* ------------------------------------------------------------------------- */
     108                 : LOCAL int       handle_remote_cancel (MinItemParser * extif_message,
     109                 :                                       int case_id);
     110                 : /* ------------------------------------------------------------------------- */
     111                 : LOCAL int       splithex (char *hex, int *dev_id, int *case_id);
     112                 : /* ------------------------------------------------------------------------- */
     113                 : LOCAL int       handle_remote_sendreceive (MinItemParser * extif_message,
     114                 :                                            int dev_id);
     115                 : /* ------------------------------------------------------------------------- */
     116                 : LOCAL slave_info *find_slave_by_addrinfo (struct addrinfo *ai, 
     117                 :                                           DLListIterator *itp);
     118                 : /* ------------------------------------------------------------------------- */
     119                 : 
     120                 : /* ------------------------------------------------------------------------- */
     121                 : /* FORWARD DECLARATIONS */
     122                 : void            master_report (int run_id, int execution_result,
     123                 :                                int test_result, char *desc);
     124                 : /* ==================== LOCAL FUNCTIONS ==================================== */
     125                 : /** Function used to split string looking like name=value into 2 parts. 
     126                 :  *  It was necessary, because parser has only functionality to extract value 
     127                 :  *  only if name is known. Remember to deallocate "name" and "value" after
     128                 :  *  they are not needed.
     129                 :  * @param input [in] string to be split
     130                 :  * @param name [out] points to string containing part before "=" sign
     131                 :  * @param var [out] points to string containing part after "=" sign
     132                 :  * @return result of operation (0 if ok, -1 in case of problems); "name"
     133                 :  * and "value" will be NULL if splitting fails.
     134                 : */
     135                 : LOCAL int split_string_eq (char *input, char **name, char **var)
     136               1 : {
     137                 : 
     138                 :         char           *delimiter;
     139                 :         int             name_size;
     140                 :         int             var_size;
     141                 : 
     142               1 :         delimiter = strchr (input, '=');
     143               1 :         if (delimiter == NULL) {
     144               0 :                 name = NULL;
     145               0 :                 var = NULL;
     146               0 :                 return -1;
     147                 :         }
     148                 : 
     149               1 :         var_size = strlen (delimiter + 1) + 1;
     150               1 :         name_size = strlen (input) - strlen (delimiter) + 1;
     151                 : 
     152               1 :         *name = NEW2 (char, name_size);
     153               1 :         snprintf (*name, name_size, "%s", input);
     154               1 :         *var = NEW2 (char, var_size);
     155               1 :         sprintf (*var, "%s", delimiter + 1);
     156               1 :         MIN_DEBUG ("name = %s, var = %s", *name, *var);
     157                 : 
     158               1 :         return 0;
     159                 : 
     160                 : }
     161                 : /* ------------------------------------------------------------------------- */
     162                 : LOCAL int
     163                 : extif_send_ipc_sendrcv (long receipent, char *data_name, char *data_value)
     164               1 : {
     165                 :         MsgBuffer       data_message;
     166               1 :         data_message.type_ = MSG_SNDRCV;
     167               1 :         data_message.sender_ = getpid ();
     168               1 :         data_message.receiver_ = receipent;
     169               1 :         sprintf (data_message.message_, "%s", data_name);
     170               1 :         sprintf (data_message.desc_, "%s", data_value);
     171                 : 
     172               1 :         return mq_send_message (mq_id, &data_message);
     173                 : }
     174                 : /* ------------------------------------------------------------------------- */
     175                 : LOCAL int get_id_from_slavename (char *slavename)
     176               1 : {
     177               1 :         DLListIterator  work_slave_item = DLListNULLIterator;
     178                 :         slave_info     *work_slave_entry;
     179               1 :         work_slave_item = dl_list_head (ms_assoc);
     180               1 :         int             retval = -1;
     181               1 :         if (strcmp (slavename, "master") == 0)
     182               0 :                 retval = 0xdead;
     183                 :         else {
     184               2 :                 while (work_slave_item != DLListNULLIterator) {
     185               1 :                         work_slave_entry =
     186                 :                             (slave_info *) dl_list_data (work_slave_item);
     187               1 :                         if (strcasecmp
     188                 :                             (tx_share_buf (work_slave_entry->slave_name_),
     189                 :                              slavename) == 0) {
     190               1 :                                 retval = work_slave_entry->slave_id_;
     191               1 :                                 break;
     192                 :                         }
     193               0 :                         work_slave_item = dl_list_next (work_slave_item);
     194                 :                 }
     195                 :         }
     196               1 :         return retval;
     197                 : }
     198                 : /* ------------------------------------------------------------------------- */
     199                 : LOCAL int extif_msg_handle_release (MinItemParser * extif_message)
     200               1 : {
     201                 :         /*restore original "complete" callback if allowed, otherwise mark that 
     202                 :            it's allowed */
     203               1 :         send_to_master (0, "release 0");
     204                 : 
     205               1 :         if (ok_to_break == ESTrue) {
     206                 : #ifdef MIN_EXTIF
     207               0 :                 tfwif_callbacks.complete_callback_ = original_complete_callback;
     208                 : #else
     209                 :                 ;
     210                 : #endif
     211                 :         } else
     212               1 :                 ok_to_break = ESTrue;
     213                 :         
     214               1 :         return 0;
     215                 : }
     216                 : /* ------------------------------------------------------------------------- */
     217                 : LOCAL void
     218                 : tec_ms_handle_data_request (int slave_id, char *varname, long requester)
     219               1 : {
     220               1 :         DLListIterator  work_data_item = DLListNULLIterator;
     221                 :         received_data  *work_data_entry;
     222                 :         MsgBuffer       ipc_message;
     223               1 :         pthread_mutex_lock (&tec_mutex_);
     224                 : 
     225               1 :         work_data_item = dl_list_head (EXTIF_received_data);
     226               2 :         while (work_data_item != DLListNULLIterator) {
     227               0 :                 work_data_entry =
     228                 :                     (received_data *) dl_list_data (work_data_item);
     229               0 :                 MIN_DEBUG (" > %d : %d < ", work_data_entry->sender_id_,
     230                 :                              slave_id);
     231               0 :                 MIN_DEBUG (" > %s : %s < ", work_data_entry->data_name_,
     232                 :                              varname);
     233                 : 
     234               0 :                 if ((work_data_entry->sender_id_ == slave_id) &&
     235                 :                     (strcmp (work_data_entry->data_name_, varname) == 0)) {
     236                 :                         /*data entry exists already - data was received */
     237               0 :                         MIN_DEBUG ("FOUND SOME DATA ENTRY");
     238               0 :                         break;
     239                 :                 }
     240               0 :                 work_data_item = dl_list_next (work_data_item);
     241                 :         }
     242               1 :         if (work_data_item != DLListNULLIterator) {
     243               0 :                 work_data_entry->requested_by_ = requester;
     244               0 :                 ipc_message.type_ = MSG_SNDRCV;
     245               0 :                 ipc_message.sender_ = getpid ();
     246               0 :                 ipc_message.receiver_ = work_data_entry->requested_by_;
     247               0 :                 sprintf (ipc_message.message_, "%s",
     248                 :                          work_data_entry->data_name_);
     249               0 :                 sprintf (ipc_message.desc_, "%s", work_data_entry->data_);
     250               0 :                 MIN_DEBUG ("returning data");
     251               0 :                 mq_send_message (mq_id, &ipc_message);
     252                 :         } else {
     253               1 :                 work_data_entry = NEW (received_data);
     254               1 :                 work_data_entry->sender_id_ = slave_id;
     255               1 :                 sprintf (work_data_entry->data_name_, "%s", varname);
     256               1 :                 work_data_entry->requested_by_ = requester;
     257               1 :                 MIN_DEBUG ("Caching request:");
     258               1 :                 MIN_DEBUG ("sender_id_ = %d", work_data_entry->sender_id_);
     259               1 :                 MIN_DEBUG ("varname = %s", work_data_entry->data_name_);
     260               1 :                 dl_list_add (EXTIF_received_data, (void *)work_data_entry);
     261                 :         }
     262               1 :         pthread_mutex_unlock (&tec_mutex_);
     263               1 : }
     264                 : /* ------------------------------------------------------------------------- */
     265                 : LOCAL int extif_msg_handle_command (MinItemParser * extif_message)
     266               2 : {
     267                 : 
     268               2 :         char           *srcaddr = NULL;
     269               2 :         char           *destaddr = NULL;
     270               2 :         char           *token = NULL;
     271               2 :         int             dev_id = 0;
     272               2 :         int             case_id = -1;
     273               2 :         int             retval = 0;
     274                 :         TScripterKeyword kw;
     275                 : 
     276               2 :         mip_get_next_string (extif_message, &srcaddr);
     277               2 :         mip_get_next_string (extif_message, &destaddr);
     278               2 :         splithex (destaddr, &dev_id, &case_id);
     279               2 :         MIN_DEBUG (">>destaddr = %s<<", destaddr);
     280               2 :         MIN_DEBUG (">> dev_id = %d, case_id = %d<<", dev_id, case_id);
     281               2 :         mip_get_next_string (extif_message, &token);
     282                 : 
     283               2 :         MIN_DEBUG ("%s: Keyword %s", __FUNCTION__,
     284                 :                     token != INITPTR ? token : "NULL");
     285                 : 
     286               2 :         kw = get_keyword (token);
     287               2 :         switch (kw) {
     288                 :         case EKeywordRequest:
     289                 :         case EKeywordRelease:
     290                 :         case EKeywordSet:
     291                 :         case EKeywordUnset:
     292               0 :                 retval = handle_remote_event (kw, extif_message);
     293               0 :                 goto EXIT;
     294                 :                 break;
     295                 :         case EKeywordRun:
     296               1 :                 retval = handle_remote_run (extif_message);
     297               0 :                 goto EXIT;
     298                 :                 break;
     299                 :         case EKeywordResume:
     300               0 :                 break;
     301                 :         case EKeywordCancel:
     302               0 :                 retval = handle_remote_cancel (extif_message, case_id);
     303               0 :                 goto EXIT;
     304                 :                 break;
     305                 :         case EKeywordPause:
     306               0 :                 retval = handle_remote_pause (extif_message, case_id);
     307               0 :                 goto EXIT;
     308                 :                 break;
     309                 :         case EKeywordCancelIfError:
     310               0 :                 break;
     311                 :         case EKeywordSendreceive:
     312               1 :                 splithex (srcaddr, &dev_id, &case_id);
     313               1 :                 MIN_DEBUG (">>> %s : %d <<<", srcaddr, dev_id);
     314               1 :                 retval = handle_remote_sendreceive (extif_message, dev_id);
     315               1 :                 goto EXIT;
     316                 :                 break;
     317                 :         default:
     318                 :         case EKeywordUnknown:
     319               0 :                 MIN_WARN ("%s: unhandled keyword %s", __FUNCTION__, token);
     320                 :                 break;
     321                 :         }
     322               1 : EXIT:
     323               1 :         return retval;
     324                 : }
     325                 : /* ------------------------------------------------------------------------- */
     326                 : /** Function handles RCP message containing sendreceive command
     327                 : */
     328                 : LOCAL int handle_remote_sendreceive (MinItemParser * extif_message, int dev_id)
     329               1 : {
     330                 : 
     331               1 :         char           *data = NULL;
     332               1 :         char           *data_value = NULL;
     333               1 :         char           *data_name = NULL;
     334               1 :         int             retval = 0;
     335                 :         DLListIterator  work_data_item;
     336                 :         received_data  *work_data_entry;
     337                 : 
     338                 :         /*check if data entry exists in list, i. e. it was
     339                 :            already requested */
     340               1 :         mip_get_next_string (extif_message, &data);
     341                 : 
     342               1 :         retval = split_string_eq (data, &data_name, &data_value);
     343               1 :         if (retval != 0) {
     344               0 :                 MIN_WARN ("Faulty message format");
     345               0 :                 return -1;
     346                 :         }
     347                 : 
     348               1 :         pthread_mutex_lock (&tec_mutex_);
     349               1 :         work_data_item = dl_list_head (EXTIF_received_data);
     350               2 :         while (work_data_item != DLListNULLIterator) {
     351               1 :                 work_data_entry =
     352                 :                     (received_data *) dl_list_data (work_data_item);
     353               1 :                 if ((work_data_entry->sender_id_ == dev_id)
     354                 :                     && ((strcasecmp (work_data_entry->data_name_, data_name))
     355                 :                         == 0)) {
     356               1 :                         MIN_DEBUG (" > %d : %d < ",
     357                 :                                     work_data_entry->sender_id_, dev_id);
     358               1 :                         MIN_DEBUG (" > %s : %s < ",
     359                 :                                     work_data_entry->data_name_, data_name);
     360               1 :                         break;
     361                 :                 }
     362               0 :                 work_data_item = dl_list_next (work_data_item);
     363                 :         }
     364                 : 
     365               1 :         if (work_data_item == DLListNULLIterator) {
     366                 :                 /*no-one mentioned this data yet, create an entry */
     367               0 :                 work_data_entry = NEW (received_data);
     368               0 :                 work_data_entry->sender_id_ = dev_id;
     369               0 :                 sprintf (work_data_entry->data_name_, "%s", data_name);
     370               0 :                 sprintf (work_data_entry->data_, "%s", data_value);
     371               0 :                 work_data_entry->requested_by_ = 0;
     372               0 :                 dl_list_add (EXTIF_received_data, (void *)work_data_entry);
     373               0 :                 MIN_DEBUG ("sender_id_ = %d", work_data_entry->sender_id_);
     374               0 :                 MIN_DEBUG ("varname = %s", work_data_entry->data_name_);
     375               0 :                 MIN_DEBUG ("EXTIF received data has now %d entries",
     376                 :                              dl_list_size (EXTIF_received_data));
     377                 :         } else {
     378               1 :                 MIN_DEBUG ("data entry found");
     379               1 :                 sprintf (work_data_entry->data_, "%s", data_value);
     380               1 :                 extif_send_ipc_sendrcv (work_data_entry->requested_by_,
     381                 :                                       data_name, data_value);
     382                 :                 /* removing used variable from buffer */
     383               1 :                 DELETE ( work_data_entry );
     384               1 :                 dl_list_remove_it(work_data_item);
     385                 :         }
     386               1 :         pthread_mutex_unlock (&tec_mutex_);
     387               1 :         return 0;
     388                 : }
     389                 : /* ------------------------------------------------------------------------- */
     390                 : /**Function handles RCP message containing "remote run" command.
     391                 :  * @param extif_message - pointer to item parser containing received message. 
     392                 :  * Assume that get_next_string was called several times, until "run" command
     393                 :  * was extracted - so next get_string will give first parameter to run keyword.
     394                 :  * @return result of operation - 0 if ok.
     395                 : */
     396                 : LOCAL int handle_remote_run (MinItemParser * extif_message)
     397               1 : {
     398               1 :         char           *module = NULL;
     399                 :         filename_t      module_filename;
     400               1 :         char           *casefile = NULL;
     401               1 :         char           *casefile_con = NULL;    /*test case's config */
     402               1 :         char           *temp_string = NULL;
     403               1 :         int             caseid = 0;
     404               1 :         int             result = 0;
     405               1 :         int             cont_flag = 0;
     406               1 :         int             check_result = 0;
     407               1 :         int             i = 0;  /*general purpose loop iterator */
     408               1 :         int             mod_found = 0, conf_found = 0;
     409               1 :         DLListIterator  work_module_item = DLListNULLIterator, it;
     410               1 :         test_module_info_s *work_module = INITPTR;
     411               1 :         DLListIterator  work_case_item = DLListNULLIterator;
     412                 :         char           *message;
     413               1 :         int             error_code = 0;
     414               1 :         DLList         *conf_list = dl_list_create ();  /* helper list for 
     415                 :                                                          * adding module */
     416                 :         title_string_t  tc_title;
     417               1 :         TParsingType    parsing = ENormalParsing;
     418               1 :         char           *casetitle = NULL;
     419                 :         filename_t      name;
     420                 : #ifndef MIN_EXTIF
     421                 :         test_case_s    *work_case;
     422                 : #endif
     423               1 :         result = mip_get_string (extif_message, "module=", &module);
     424               1 :         if (result != 0) {
     425               0 :                 MIN_WARN ("remote module not specified");
     426               0 :                 goto FAULT;
     427                 :         }
     428                 : 
     429               1 :         result = mip_get_string (extif_message, "testcasefile=", &casefile);
     430               1 :         if (result != 0) {
     431               1 :                 MIN_WARN ("test case file not specified");
     432               1 :                 error_code = -1;
     433               1 :                 casefile = NULL;
     434                 :         }
     435               1 :         result = mip_get_int (extif_message, "testcasenum=", &caseid);
     436               1 :         if (result != 0) {
     437               0 :                 MIN_WARN ("Faulty command: %s", 
     438                 :                              extif_message->item_line_section_);
     439               0 :                 MIN_WARN ("test case id not specified");
     440               0 :                 error_code = -1;
     441               0 :                 goto FAULT;
     442                 :         }
     443                 : 
     444                 :         /*
     445                 :         ** Check if we have the module already instantiated
     446                 :         */
     447               1 :         if (!strcmp (casefile, "dummy.cfg"))
     448               0 :                 conf_found = 1;
     449               0 :         for (work_module_item = dl_list_head (instantiated_modules);
     450               0 :              work_module_item != DLListNULLIterator;
     451               0 :              work_module_item = dl_list_next (work_module_item))
     452                 :         {
     453               0 :                 tm_get_module_filename (work_module_item, name);
     454               0 :                 if (strcmp (module, name) == 0) {
     455               0 :                         mod_found = 1;
     456                 :                         /*
     457                 :                         ** The module is already instantiated.
     458                 :                         ** Next check the configuration file.
     459                 :                         */
     460                 :                         for (it = dl_list_head (tm_get_cfg_filenames 
     461               0 :                                                 (work_module_item));
     462               0 :                              it != DLListNULLIterator;
     463               0 :                              it = dl_list_next (it)) {
     464               0 :                                 if (strcmp (dl_list_data (it),
     465                 :                                             casefile)  == 0) {
     466               0 :                                         conf_found = 1;
     467                 :                                 }
     468                 :                         }
     469               0 :                         if (conf_found && mod_found)
     470               0 :                                 goto MODULE_PRESENT;
     471                 :                 }
     472                 :                 
     473                 :                 
     474                 :         }
     475                 : 
     476                 :         /*adding module specified in run command here */
     477               0 :         temp_string = NEW2 (char, strlen (casefile) + 1);
     478               0 :         sprintf (temp_string, "%s", casefile);
     479                 :         /*add specified testcase file only if it is 
     480                 :         specified as absolute path or exists in lib directories*/
     481               0 :         if (((*temp_string)=='/')||
     482                 : 
     483                 :              (ec_search_lib(temp_string)) != -1){
     484               0 :                 dl_list_add (conf_list, (void *)temp_string);
     485                 :         } else {
     486               0 :                 MIN_WARN ("test case file %s not found", temp_string);
     487                 :         }
     488                 : #ifdef MIN_EXTIF
     489               0 :         min_if_module_add (module, !strcmp (casefile, "dummy.cfg") ?
     490                 :                            "" : temp_string);
     491                 : #else
     492               0 :         ec_add_module (module, conf_list, 0, 0);
     493                 : #endif
     494                 :         /*wait for module to return testcases */
     495               0 : MODULE_PRESENT:
     496               0 :         while (cont_flag == 0) {
     497               0 :                 usleep (500000);
     498               0 :                 i++;
     499               0 :                 work_module_item = dl_list_head (instantiated_modules);
     500               0 :                 cont_flag = 1;
     501               0 :                 while (work_module_item != DLListNULLIterator) {
     502               0 :                         check_result = tm_get_status (work_module_item);
     503               0 :                         if (check_result == TEST_MODULE_READY)
     504               0 :                                 cont_flag = cont_flag | 1;
     505                 :                         else
     506               0 :                                 cont_flag = 0;
     507               0 :                         work_module_item = dl_list_next (work_module_item);
     508                 :                 }
     509               0 :                 if (i > 20) {
     510               0 :                         MIN_WARN ("timeout on module instantiation");
     511               0 :                         goto FAULT;
     512                 :                 }
     513                 :         }
     514                 :         /*Now fetch correct testcase */
     515               0 :         work_module_item = dl_list_head (instantiated_modules);
     516               0 :         while (work_module_item != DLListNULLIterator) {
     517               0 :                 work_module =
     518                 :                     (test_module_info_s *) dl_list_data (work_module_item);
     519               0 :                 tm_get_module_filename (work_module_item, module_filename);
     520               0 :                 if (strcmp (module_filename, module) == 0)
     521               0 :                         break;
     522               0 :                 work_module_item = dl_list_next (work_module_item);
     523                 :         }
     524                 : 
     525               0 :         if (work_module_item == DLListNULLIterator) {
     526               0 :                 MIN_WARN ("Specified module not configured");
     527               0 :                 error_code = -2;
     528               0 :                 goto FAULT;
     529                 :         }
     530                 : 
     531                 :         /* test case title may contain whitespaces, that's why parsing type
     532                 :          * is changed to QuoteStyle. if passing this optional value, it
     533                 :          * must be quoted */
     534               0 :         parsing=mip_get_parsing_type(extif_message);
     535               0 :         mip_set_parsing_type (extif_message, EQuoteStyleParsing);
     536               0 :         result = mip_get_string (extif_message, "testcasetitle=", &casetitle);
     537               0 :         mip_set_parsing_type (extif_message, parsing);
     538               0 :         if (result == 0) {
     539               0 :             MIN_INFO ("test case title specified, omitting id");
     540                 :             
     541               0 :             work_case_item = dl_list_head (tm_get_tclist (work_module_item));
     542               0 :             while (work_case_item != DLListNULLIterator) {
     543               0 :                     tc_get_title (work_case_item, tc_title);
     544               0 :                     if (strcmp(tc_title, casetitle) == 0) {
     545               0 :                             if (dl_list_size
     546                 :                                 (tm_get_cfg_filenames (work_module_item)) < 2)
     547               0 :                                     break;
     548                 :                             /*if module has 0 or 1 config file, 
     549                 :                              * we have already found case */
     550                 :                             else {
     551               0 :                                     tc_get_cfg_filename (work_case_item,
     552                 :                                                          casefile_con);
     553               0 :                                     check_result =
     554                 :                                         strcmp (casefile_con, casefile);
     555               0 :                                     DELETE (casefile_con);
     556               0 :                                     if (check_result == 0)
     557               0 :                                             break;
     558                 :                                     /*id and testcase file match */
     559                 :                                 }
     560                 :                     }
     561               0 :                     work_case_item = dl_list_next (work_case_item);
     562                 :             }
     563                 : 
     564                 :         } else {
     565               0 :             MIN_INFO ("test case title not specified, using id");
     566               0 :             work_case_item = dl_list_head (tm_get_tclist (work_module_item));
     567               0 :             while (work_case_item != DLListNULLIterator) {
     568               0 :                     if (tc_get_id (work_case_item) == caseid) {
     569               0 :                             if (dl_list_size
     570                 :                                 (tm_get_cfg_filenames (work_module_item)) < 2)
     571               0 :                                     break;
     572                 :                         /*if module has 0 or 1 config file, 
     573                 :                          * we have already found case */
     574                 :                             else {
     575               0 :                                     tc_get_cfg_filename (work_case_item,
     576                 :                                                          casefile_con);
     577               0 :                                     check_result =
     578                 :                                         strcmp (casefile_con, casefile);
     579               0 :                                     DELETE (casefile_con);
     580               0 :                                     if (check_result == 0)
     581               0 :                                             break;
     582                 :                                     /*id and testcase file match */
     583                 :                                 }
     584                 :                     }
     585               0 :                     work_case_item = dl_list_next (work_case_item);
     586                 :             }
     587                 :         }
     588                 : 
     589               0 :         if (work_case_item == DLListNULLIterator) {
     590               0 :                 MIN_WARN ("Wrong case id");
     591               0 :                 error_code = -2;
     592               0 :                 goto FAULT;
     593                 :         }
     594                 : 
     595               0 :         result = ec_exec_test_case (work_case_item);
     596               0 :         caseid = dl_list_size (selected_cases);
     597                 : #ifndef MIN_EXTIF
     598               0 :         work_case_item = dl_list_tail (selected_cases);
     599               0 :         work_case = dl_list_data (work_case_item);
     600               0 :         work_case->ip_slave_case_ = 1;
     601                 : #endif
     602                 : 
     603               0 :         if (result != 0) {
     604               0 :                 error_code = -2;
     605               0 :                 MIN_WARN ("Error in test case execution");
     606               0 :                 goto FAULT;
     607                 :         }
     608               0 :         ok_to_break = ESFalse;
     609               0 :         send_to_master (caseid, "remote run started");
     610               0 :         return 0;
     611                 : 
     612               0 :       FAULT:
     613                 :         /*test case could not be started for some reason */
     614               0 :         message = NEW2 (char, 30);
     615               0 :         sprintf (message, "remote run error result=%d", error_code);
     616               0 :         send_to_master (0, message);
     617               0 :         DELETE (module);
     618               0 :         DELETE (message);
     619               0 :         DELETE (casefile);
     620               0 :         return 0;
     621                 : }
     622                 : /* ------------------------------------------------------------------------- */
     623                 : /**Function implemens handling of "remote pause" command 
     624                 :  * @param extif_message - pointer to item parser containing received message.
     625                 :  *  Assume that get_next_string was called several times, until "pause" 
     626                 :  * command was extracted
     627                 :  * @param case_id - dev id extracted from external controller address field
     628                 :  * @return result of operation - 0 if ok.
     629                 :  */
     630                 : LOCAL int handle_remote_pause (MinItemParser * extif_message, int case_id)
     631               0 : {
     632               0 :         return 0;
     633                 : }
     634                 : /* ------------------------------------------------------------------------- */
     635                 : /**Function implemens handling of "remote cancel" command 
     636                 :  * @param extif_message - pointer to item parser containing received message. 
     637                 :  * Assume   that get_next_string was called several times, until "cancel" 
     638                 :  * command was extracted
     639                 :  * @param case_id - dev id extracted from external controller address field
     640                 :  * @return result of operation - 0 if ok.
     641                 : */
     642                 : LOCAL int handle_remote_cancel (MinItemParser * extif_message, int case_id)
     643               0 : {
     644               0 :         DLListIterator  work_case_item = DLListNULLIterator;
     645               0 :         int             result = 0;
     646                 : 
     647               0 :         work_case_item = dl_list_at (selected_cases, case_id - 1);
     648                 : 
     649               0 :         if (work_case_item != DLListNULLIterator) {
     650               0 :                 result = ec_abort_test_case (work_case_item);
     651                 :         } else {
     652               0 :                 result = -1;
     653                 :         }
     654                 : 
     655               0 :         if (result == 0) {
     656               0 :                 send_to_master (case_id, "remote cancel");
     657                 :         }
     658                 :         /* Protocol specification describes only response to successfull 
     659                 :          * remote pause. If the pause was not successfull, master test 
     660                 :          * case should fail. Based on that, if remote pause fails for whatever
     661                 :          * reason, response will not be sent - what should cause master test
     662                 :          * case fo fail.
     663                 :          */
     664               0 :         return result;
     665                 : }
     666                 : /* ------------------------------------------------------------------------- */
     667                 : /**Function splits RCP's adress string fields into two ints.
     668                 :  * @param hex [in] string to be split, has to be 8 characters, otherwise
     669                 :  *  function fails
     670                 :  * @param dev_id [out] pointer to int that will hold device id
     671                 :  * @param case_id [out] pointer to int that will hold case id
     672                 :  * @return result of operation, 0 if ok
     673                 : */
     674                 : LOCAL int splithex (char *hex, int *dev_id, int *case_id)
     675               5 : {
     676                 :         char            dev_id_c[5];
     677                 :         char            case_id_c[5];
     678                 :         char           *endptr;
     679                 : 
     680               5 :         if (strlen (hex) != 8) {
     681               0 :                 return -1;
     682                 :         }
     683                 : 
     684               5 :         snprintf (dev_id_c, 5, "%s", hex);
     685               5 :         snprintf (case_id_c, 5, "%s", hex + 4);
     686               5 :         *dev_id = strtol (dev_id_c, &endptr, 16);
     687               5 :         *case_id = strtol (case_id_c, &endptr, 16);
     688                 : 
     689               5 :         return 0;
     690                 : }
     691                 : /* ------------------------------------------------------------------------- */
     692                 : /** Function writes text representation of slave adress, in hexadecimal with 
     693                 :  * leading zeros
     694                 :  * @param deviceid identifier of device
     695                 :  * @param caseid id of testcase
     696                 :  * @return string containing proper representation, or INITPTR 
     697                 :  * in case of problem.
     698                 :  */
     699                 : 
     700                 : LOCAL char     *writehex (int devid, int caseid)
     701               9 : {
     702               9 :         char           *hex = NEW2 (char, 9);
     703               9 :         int             val = devid * 0x10000 + caseid;
     704                 : 
     705                 :         if (val > 0xffffffff) {
     706                 :                 DELETE (hex);
     707                 :         } else {
     708               9 :                 sprintf (hex, "%.8x", val);
     709                 :         }
     710                 : 
     711               9 :         return hex;
     712                 : }
     713                 : /* ------------------------------------------------------------------------- */
     714                 : /**Function recognizes message received from external controller and calls 
     715                 :  * apropriate handler
     716                 :  * @param extif_message pointer to MinItemParser with parser created
     717                 :  *  from message string.
     718                 :  * @return result of operation, 0 if successfull.
     719                 :  */
     720                 : LOCAL int min_if_dispatch_extif_msg (MinItemParser * extif_message)
     721              12 : {
     722                 :         /*strings used to parse fields of RCP message */
     723              12 :         char           *messtype = NULL;
     724                 : 
     725              12 :         int             result = 666;
     726                 : 
     727              12 :         result = mip_get_string (extif_message, "", &messtype);
     728                 : 
     729              12 :         if (result != 0) {
     730               0 :                 MIN_WARN ("Could not get EXTIF message type");
     731               0 :                 goto DISPATCH_EXIT;
     732                 :         }
     733                 : 
     734              12 :         if (strcasestr (messtype, "reserve") != NULL) {
     735                 : 
     736               3 :                 result = extif_msg_handle_reserve (extif_message);
     737               3 :                 goto DISPATCH_EXIT;
     738                 :         }
     739                 : 
     740               9 :         if (strcasestr (messtype, "release") != NULL) {
     741               1 :                 result = extif_msg_handle_release (extif_message);
     742               1 :                 goto DISPATCH_EXIT;
     743                 :         }
     744                 : 
     745               8 :         if (strcasestr (messtype, "response") != NULL) {
     746                 : #ifdef MIN_EXTIF
     747               2 :                 result = extif_msg_handle_response (extif_message);
     748                 : #else
     749               4 :                 result = tcp_msg_handle_response (extif_message);
     750                 : 
     751                 : #endif
     752               6 :                 goto DISPATCH_EXIT;
     753                 :         }
     754                 : 
     755               2 :         if (strcasestr (messtype, "remote") != NULL) {
     756               2 :                 result = extif_msg_handle_command (extif_message);
     757               1 :                 goto DISPATCH_EXIT;
     758                 :         }
     759                 : 
     760              11 :       DISPATCH_EXIT:
     761              11 :         DELETE (messtype);
     762                 : 
     763              11 :         return result;
     764                 : }
     765                 : /* ------------------------------------------------------------------------- */
     766                 : /**Function handles "response" message coming from external controller
     767                 :  * @param extif_message pointer to item parser. It is assumed that 
     768                 :  * mip_get_string was  executed once for this parser to get first "word"
     769                 :  * @return result of operation, 0 if ok.
     770                 :  */
     771                 : #ifdef MIN_EXTIF
     772                 : LOCAL int extif_msg_handle_response (MinItemParser * extif_message)
     773               2 : {
     774               2 :         char           *command = INITPTR;
     775               2 :         char           *param1 = NULL;
     776               2 :         char           *srcid = INITPTR;
     777               2 :         char           *destid = INITPTR;
     778               2 :         int             result = 666;
     779               2 :         int             retval = 666;
     780               2 :         int             slave_id = 0;
     781               2 :         int             case_id = 0;
     782                 :         MsgBuffer       ipc_message;
     783               2 :         slave_info     *slave_entry = INITPTR;
     784               2 :         char           *slave_name = NULL;
     785                 :         DLListIterator  slave_entry_item;
     786                 : 
     787               2 :         mip_get_next_string (extif_message, &srcid);
     788                 : 
     789               2 :         mip_get_next_string (extif_message, &destid);
     790                 : 
     791               2 :         mip_get_next_string (extif_message, &command);
     792                 : 
     793               2 :         if (strcasecmp (command, "reserve") == 0) {
     794               1 :                 retval =
     795                 :                     mip_get_next_tagged_int (extif_message, "result=", &result);
     796                 : 
     797               1 :                 if (retval == -1)
     798               1 :                         mip_get_next_int (extif_message, &result);
     799                 :                 /*result was not tagged int */
     800               1 :                 if (retval == -1)
     801               1 :                         result = 0;
     802                 : 
     803                 :                 /*it seems that result was not send, assume success */
     804                 : 
     805                 :                 /* now find slave entry without device id. Currently
     806                 :                  * external controller picks first available slave during
     807                 :                  * allocation, so we do the same */
     808               1 :                 slave_entry_item = dl_list_head (ms_assoc);
     809               2 :                 while (slave_entry_item != INITPTR) {
     810               1 :                         slave_entry =
     811                 :                             (slave_info *) dl_list_data (slave_entry_item);
     812               1 :                         MIN_DEBUG (" slave: %d, %s", slave_entry->slave_id_,
     813                 :                                    tx_share_buf (slave_entry->slave_name_));
     814               1 :                         if (slave_entry->slave_id_ == 0) {
     815               1 :                                 slave_name = tx_get_buf 
     816                 :                                         (slave_entry->slave_name_);
     817               1 :                                 break;
     818                 :                         }
     819               0 :                         slave_entry_item = dl_list_next (slave_entry_item);
     820                 :                 }
     821               1 :                 if (slave_name == NULL) {
     822               0 :                         MIN_WARN ("Unrequested response ?");
     823               0 :                         retval = -1;
     824               0 :                         goto out;
     825                 :                 }
     826               1 :                 splithex (srcid, &slave_id, &case_id);
     827               1 :                 slave_entry->slave_id_ = slave_id;
     828               1 :                 if (retval == -1)
     829               1 :                         result = 0;
     830                 :                 /*it seems that result was not sent, assume success */
     831               1 :                 ipc_message.sender_ = ec_settings.engine_pid_;
     832               1 :                 ipc_message.receiver_ = own_id;
     833               1 :                 ipc_message.type_ = MSG_EXTIF;
     834               1 :                 ipc_message.special_ = 0;
     835               1 :                 ipc_message.extif_msg_type_ = EResponseSlave;
     836               1 :                 ipc_message.param_ = result;
     837               1 :                 MIN_DEBUG ("ipc sending with result %d", result);
     838               1 :                 mq_send_message (mq_id, &ipc_message);
     839               1 :                 DELETE (slave_name);
     840               1 :                 retval = 0;
     841               1 :         } else if (strcasecmp (command, "release") == 0) {
     842               1 :                 retval =
     843                 :                     mip_get_next_tagged_int (extif_message, "result=", &result);
     844               1 :                 if (retval == -1)
     845               1 :                         mip_get_next_int (extif_message, &result);
     846                 :                 /*result was not tagged int */
     847               1 :                 if (retval == -1)
     848               1 :                         result = 0;
     849                 :                 /*it seems that result was not send, assume success */
     850               1 :                 ipc_message.sender_ = ec_settings.engine_pid_;
     851               1 :                 ipc_message.receiver_ = own_id;
     852               1 :                 ipc_message.type_ = MSG_EXTIF;
     853               1 :                 ipc_message.param_ = result;
     854               1 :                 ipc_message.special_ = 0;
     855               1 :                 ipc_message.extif_msg_type_ = EResponseSlave;
     856               1 :                 MIN_DEBUG ("ipc sending with result %d", result);
     857               1 :                 mq_send_message (mq_id, &ipc_message);
     858                 :                 /*slave released, remove it from ms_assoc */
     859               1 :                 splithex (srcid, &slave_id, &case_id);
     860               1 :                 slave_entry_item = dl_list_head (ms_assoc);
     861               2 :                 while (slave_entry_item != DLListNULLIterator) {
     862                 :                         
     863               1 :                         slave_entry =
     864                 :                             (slave_info *) dl_list_data (slave_entry_item);
     865               1 :                         if (slave_entry->slave_id_ == slave_id) {
     866               1 :                                 DELETE (slave_entry);
     867               1 :                                 dl_list_remove_it (slave_entry_item);
     868               1 :                                 break;
     869                 :                         }
     870                 : 
     871                 :                 }
     872               1 :                 retval = 0;
     873               0 :         } else if (strcasecmp (command, "remote") == 0) {
     874               0 :                 mip_get_next_string (extif_message, &command);
     875               0 :                 if (strcasecmp (command, "run") == 0) {
     876               0 :                         splithex (srcid, &slave_id, &case_id);
     877                 :                         /*translate received caseid into proper 
     878                 :                         number that can be stored in scripter*/
     879               0 :                         case_id = (slave_id<<16) + case_id;
     880               0 :                         mip_get_next_string (extif_message, &param1);
     881               0 :                         if (strcasecmp (param1, "started") == 0) {
     882               0 :                                 ipc_message.sender_ = ec_settings.engine_pid_;
     883               0 :                                 ipc_message.receiver_ = own_id;
     884               0 :                                 ipc_message.type_ = MSG_EXTIF;
     885               0 :                                 ipc_message.special_ = case_id;
     886               0 :                                 ipc_message.param_ = 0;
     887               0 :                                 ipc_message.extif_msg_type_ = EResponseSlave;
     888               0 :                                 MIN_DEBUG ("ipc sending with result 0");
     889               0 :                                 mq_send_message (mq_id, &ipc_message);
     890               0 :                                 retval = 0;
     891               0 :                         } else if (strcasecmp (param1, "ready") == 0) {
     892               0 :                                 mip_get_int (extif_message, "result=", &result);
     893               0 :                                 ipc_message.sender_ = ec_settings.engine_pid_;
     894               0 :                                 ipc_message.receiver_ = own_id;
     895               0 :                                 ipc_message.type_ = MSG_EXTIF;
     896               0 :                                 ipc_message.special_ = case_id;
     897               0 :                                 ipc_message.param_ = result;
     898               0 :                                 ipc_message.extif_msg_type_ =
     899                 :                                     ERemoteSlaveResponse;
     900               0 :                                 MIN_DEBUG ("ipc sending with result %d",
     901                 :                                              result);
     902               0 :                                 mq_send_message (mq_id, &ipc_message);
     903               0 :                                 retval = 0;
     904                 : 
     905               0 :                         } else if (strcasecmp (param1, "error") == 0) {
     906               0 :                                 mip_get_int (extif_message, "result=", &result);
     907               0 :                                 ipc_message.sender_ = ec_settings.engine_pid_;
     908               0 :                                 ipc_message.receiver_ = own_id;
     909               0 :                                 ipc_message.type_ = MSG_EXTIF;
     910               0 :                                 ipc_message.special_ = case_id;
     911               0 :                                 ipc_message.param_ = result;
     912               0 :                                 ipc_message.extif_msg_type_ = EResponseSlave;
     913               0 :                                 MIN_DEBUG ("ipc sending with result %d",
     914                 :                                              result);
     915               0 :                                 mq_send_message (mq_id, &ipc_message);
     916               0 :                                 retval = 0;
     917                 :                         }
     918               0 :                 } else if (strcasecmp (command, "request") == 0) {
     919               0 :                         retval =
     920                 :                             handle_remote_event_request_resp (extif_message);
     921               0 :                 } else if (strcasecmp (command, "release") == 0)
     922                 :                         /*TEMPORARY SOLUTION, INVESTIGATE EVENT SYSTEM */
     923               0 :                         retval = 0;
     924                 :         }
     925               2 :       out:
     926               2 :         DELETE (command);
     927               2 :         DELETE (param1);
     928               2 :         DELETE (srcid);
     929               2 :         DELETE (destid);
     930                 : 
     931               2 :         return retval;
     932                 : }
     933                 : #endif
     934                 : /* ------------------------------------------------------------------------- */
     935                 : /** Function handles external controller "reserve" message
     936                 :  * @param extif_message pointer to item parser. It is assumed that 
     937                 :  * mip_get_string was executed once for this parser to get first "word"
     938                 :  * @return result of operation, 0 if ok.
     939                 :  */
     940                 : LOCAL int extif_msg_handle_reserve (MinItemParser * extif_message)
     941               3 : {
     942                 :         char            rtype[11];
     943                 : #ifndef MIN_EXTIF
     944                 : 
     945               0 :         char           *srcid = INITPTR;
     946               0 :         char           *destid = INITPTR;
     947               0 :         int             dev_id = 0;
     948               0 :         int             case_id = -1;
     949                 : #endif  
     950                 :         /*change "complete case" callback */
     951               3 :         pthread_mutex_lock (&tec_mutex_);
     952               3 :         ok_to_break = ESFalse;
     953                 : 
     954                 : #ifdef MIN_EXTIF
     955               3 :         original_complete_callback = tfwif_callbacks.complete_callback_;
     956               3 :         MIN_DEBUG ("old callback = %x ", tfwif_callbacks.complete_callback_);
     957               3 :         MIN_DEBUG ("master report = %x ", master_report);
     958               3 :         tfwif_callbacks.complete_callback_ = master_report;
     959               3 :         MIN_DEBUG ("new callback = %x ", tfwif_callbacks.complete_callback_);
     960                 : #else
     961               0 :         mip_get_next_string (extif_message, &srcid);
     962               0 :         mip_get_next_string (extif_message, &destid);
     963               0 :         splithex (destid, &dev_id, &case_id);
     964               0 :         own_id = dev_id;
     965                 : #endif
     966                 : 
     967               3 :         pthread_mutex_unlock (&tec_mutex_);
     968               3 :         sprintf (rtype, "reserve 0");
     969               3 :         send_to_master (0, rtype);
     970                 : 
     971               3 :         return 0;
     972                 : }
     973                 : /* ------------------------------------------------------------------------- */
     974                 : /** Searches for slave based on address
     975                 :  * @param ai address information
     976                 :  * @param itp OUT used to pass the DLListIterator to caller
     977                 :  * @return slave_info if found, otherwise INITPTR
     978                 :  */
     979                 : LOCAL slave_info *find_slave_by_addrinfo (struct addrinfo *ai, 
     980                 :                                           DLListIterator *itp)
     981              16 : {
     982                 :        DLListIterator it;
     983                 :        slave_info *ips;
     984                 :  
     985              16 :        *itp = INITPTR;
     986                 : 
     987              39 :        for (it = dl_list_head (ms_assoc); it != INITPTR;
     988               7 :             it = dl_list_next (it)) {
     989               7 :                ips = dl_list_data (it);
     990               7 :                if (!memcmp (ai, ips->addrinfo_, sizeof (struct addrinfo)))  {
     991               0 :                        *itp = it;
     992               0 :                        return ips;
     993                 :                }
     994                 :        }
     995                 :        
     996              16 :        return INITPTR;
     997                 : }
     998                 : 
     999                 : /* ========================  FUNCTIONS ===================================== */
    1000                 : 
    1001                 : /*---------------------------------------------------------------------------*/
    1002                 : /** Function called to intitialize rcp handling
    1003                 :  */
    1004                 : void rcp_handling_init ()
    1005             124 : {
    1006             124 :         ms_assoc = dl_list_create();
    1007             124 :         EXTIF_received_data = dl_list_create();
    1008             124 : }
    1009                 : /*---------------------------------------------------------------------------*/
    1010                 : /** Clean up
    1011                 :  */
    1012                 : void rcp_handling_cleanup ()
    1013              19 : {
    1014                 :         DLListIterator  work_slave_item;
    1015                 :         DLListIterator  work_data_item;
    1016                 :         received_data  *work_data_entry;
    1017                 :         slave_info     *slave;
    1018              19 :         work_slave_item = dl_list_head (ms_assoc);
    1019              50 :         while (work_slave_item != DLListNULLIterator) {
    1020              12 :                 slave = dl_list_data (work_slave_item);
    1021              12 :                 if (slave->write_queue_)
    1022              12 :                         dl_list_free (&slave->write_queue_);
    1023              12 :                 if (slave->slave_name_)
    1024              12 :                         tx_destroy (&slave->slave_name_);
    1025              12 :                 if (slave->slave_type_)
    1026              12 :                         tx_destroy (&slave->slave_type_);
    1027              12 :                 if (slave->addrinfo_)
    1028              12 :                         freeaddrinfo (slave->addrinfo_);
    1029              12 :                 DELETE (slave);
    1030              12 :                 dl_list_remove_it (work_slave_item);
    1031              12 :                 work_slave_item = dl_list_head (ms_assoc);
    1032                 :         }
    1033              19 :         dl_list_free (&ms_assoc);
    1034                 : 
    1035              19 :         work_data_item = dl_list_head (EXTIF_received_data);
    1036              38 :         while (work_data_item != DLListNULLIterator) {
    1037               0 :                 work_data_entry =
    1038                 :                     (received_data *) dl_list_data (work_data_item);
    1039               0 :                 DELETE (work_data_entry);
    1040               0 :                 dl_list_remove_it (work_data_item);
    1041               0 :                 work_data_item = dl_list_head (EXTIF_received_data);
    1042                 :         }
    1043              19 :         dl_list_free (&EXTIF_received_data);
    1044                 : 
    1045              19 : }
    1046                 : 
    1047                 : /* ------------------------------------------------------------------------- */
    1048                 : /** Function called to send external controller message to master device.
    1049                 :  * @param tc_id id of slave's test case
    1050                 :  * @param msg NULL-terminated string containing body of message 
    1051                 :  *            (everything following adresses)
    1052                 :  */
    1053                 : void send_to_master (int tc_id, char *msg)
    1054               4 : {
    1055                 : 
    1056                 :         char           *hex;
    1057                 : 
    1058               4 :         if (tc_id != 0) {
    1059               0 :               tc_id = dl_list_size (selected_cases);
    1060                 :         }
    1061               4 :         hex = writehex (own_id, tc_id);
    1062               4 :         in->send_rcp ("response", hex, "deadbeef", msg, 0);
    1063                 : 
    1064               4 :         DELETE (hex);
    1065               4 : }
    1066                 : 
    1067                 : /*---------------------------------------------------------------------------*/
    1068                 : /** Function called to send external controller message to slave device.
    1069                 :  * @param slave_name NULL-terminated string containing slave's name
    1070                 :  * @param tc_id id of slave's test case
    1071                 :  * @param msg NULL-terminated string containing body of message 
    1072                 :  *        (everything following adresses)
    1073                 :  */
    1074                 : void
    1075                 : send_to_slave (TMSCommand command, char *slave_name, int tc_id, char *message)
    1076               5 : {
    1077               5 :         DLListIterator  slave_entry_item = DLListNULLIterator;
    1078               5 :         slave_info     *slave_entry = INITPTR;
    1079               5 :         int             slave_id = 0;
    1080                 :         char           *hex;
    1081                 : 
    1082               5 :         slave_entry_item = dl_list_head (ms_assoc);
    1083              10 :         while (slave_entry_item != DLListNULLIterator) {
    1084               5 :                 slave_entry = (slave_info *) dl_list_data (slave_entry_item);
    1085               5 :                 if (slave_entry->slave_name_ != INITPTR &&
    1086                 :                     strcmp (slave_name, 
    1087                 :                             tx_share_buf (slave_entry->slave_name_)) == 0) {
    1088               5 :                         slave_id = slave_entry->slave_id_;
    1089               5 :                         break;
    1090                 :                 }
    1091               0 :                 slave_entry_item = dl_list_next (slave_entry_item);
    1092                 :         }
    1093                 :         /* scripter keeps tc_id as a combination of slave id and testcase 
    1094                 :          * number (slave number as last 4 digits), test case id needs to 
    1095                 :          * be stripped if given at all. Not used in current implementation, 
    1096                 :          * since all calls to this function give 0 in this argument so far, 
    1097                 :          * but it might prevent problems in in case someone wants to expand 
    1098                 :          * functionality.*/
    1099               5 :         if (tc_id != 0){
    1100               0 :                 tc_id = tc_id&0xffff; /*to strip slave id*/
    1101                 :         }
    1102               5 :         hex = writehex (slave_id, tc_id);
    1103               5 :         switch (command) {
    1104                 :         case EAllocateSlave:
    1105               2 :                 sleep (1);
    1106               2 :                 in->send_rcp ("reserve", "deadbeef", hex, message, 
    1107                 :                               slave_entry->fd_);
    1108               2 :                 break;
    1109                 :         case EFreeSlave:
    1110               2 :                 in->send_rcp ("release", "deadbeef", hex, message,
    1111                 :                               slave_entry->fd_);
    1112               2 :                 break;
    1113                 :         case ERemoteSlave:
    1114               1 :           if (!strncmp (message, "run", 3))  {
    1115               1 :                         slave_entry->run_cnt_++;
    1116                 :                 }
    1117               1 :                 MIN_DEBUG ("slave_entry = %x, run count = %d",
    1118                 :                            slave_entry, slave_entry->run_cnt_);
    1119               1 :                 in->send_rcp ("remote", "deadbeef", hex, message,
    1120                 :                               slave_entry->fd_);
    1121                 :                 break;
    1122                 :         default:
    1123                 :                 break;
    1124                 :         }
    1125               5 :         DELETE (hex);
    1126               5 : }
    1127                 : /* ------------------------------------------------------------------------- */
    1128                 : /**Handler for sendreceive ipc message from slave
    1129                 :  */
    1130                 : int ec_msg_sndrcv_handler (MsgBuffer * message)
    1131               0 : {
    1132                 :         char           *hex;
    1133                 :         Text *tx;
    1134               0 :         tx = tx_create ("sendreceive ");
    1135               0 :         tx_c_append (tx, message->message_);
    1136               0 :         tx_c_append (tx, "=");
    1137               0 :         tx_c_append (tx, message->desc_);
    1138               0 :         hex = writehex (own_id, 0);
    1139               0 :         in->send_rcp ("remote", hex, "deadbeef", tx_share_buf(tx), 0);
    1140                 :         
    1141               0 :         tx_destroy (&tx);
    1142               0 :         DELETE (hex);
    1143               0 :         return 0;
    1144                 : }
    1145                 : /* ------------------------------------------------------------------------- */
    1146                 : /** Handler for ipc external controller message,
    1147                 :  * used in master/slave scenarios (hence _ms_);
    1148                 :  * since those in turn have several "subtypes",
    1149                 :  * function reads type and calls apropriate handlers.
    1150                 :  * @param message MsgBUffer containing received IPC message
    1151                 :  * @return result of the operation
    1152                 :  */
    1153                 : int ec_msg_ms_handler (MsgBuffer * message)
    1154               6 : {
    1155               6 :         char           *extifmessage = NULL;
    1156               6 :         char           *param1 = NULL;
    1157               6 :         char           *param2 = NULL;
    1158               6 :         char           *param3 = NULL;
    1159               6 :         char           *param4 = NULL;
    1160               6 :         char           *param5 = NULL;
    1161                 :         TScripterKeyword kw;
    1162               6 :         TParsingType   parsing=ENormalParsing;
    1163                 : 
    1164               6 :         MinItemParser *params = INITPTR;
    1165                 : #ifdef MIN_EXTIF
    1166               2 :         slave_info     *slave_entry = INITPTR;
    1167                 : #endif
    1168                 : 
    1169               6 :         extifmessage = NEW2 (char, strlen (message->message_) + 255);
    1170                 : 
    1171               6 :         switch (message->extif_msg_type_) {
    1172                 :         case EAllocateSlave:
    1173                 :                 /* since only master test case can send this message,
    1174                 :                    we will set own_id of this min instance to PID of this 
    1175                 :                    TMC, so that we can forward IPC messages correctly */
    1176                 : 
    1177               2 :                 own_id = message->sender_;
    1178                 : #ifdef MIN_EXTIF
    1179               1 :                 slave_entry = NEW (slave_info);
    1180               1 :                 memset (slave_entry, 0x0, sizeof (slave_info));
    1181               1 :                 slave_entry->slave_name_ = tx_create (message->message_);
    1182               1 :                 slave_entry->slave_id_ = 0;
    1183               1 :                 slave_entry->run_cnt_ = 0;
    1184               1 :                 dl_list_add (ms_assoc, (void *)slave_entry);
    1185                 : #else
    1186               1 :                 if (allocate_ip_slave (message->desc_, message->message_,
    1187                 :                                        own_id)) {
    1188               0 :                         MIN_FATAL ("slave allocation failed");
    1189               0 :                         DELETE (extifmessage);
    1190               0 :                         return -1;
    1191                 :                 }
    1192                 : #endif
    1193               2 :                 send_to_slave (EAllocateSlave, message->message_, 0,
    1194                 :                                message->desc_);
    1195               2 :                 break;
    1196                 : 
    1197                 :         case EFreeSlave:
    1198                 : 
    1199               2 :                 send_to_slave (EFreeSlave, message->message_, 0, "");
    1200               2 :                 break;
    1201                 : 
    1202                 :         case ERemoteSlave:
    1203               2 :                 MIN_DEBUG ("MESSAGE: %s\n", message->message_);
    1204               2 :                 MIN_DEBUG ("DESC: %s\n", message->desc_);
    1205               2 :                 params =
    1206                 :                     mip_create (message->desc_, 0,
    1207                 :                                 strlen (message->desc_) + 1);
    1208               2 :                 mip_get_string (params, "", &param1);
    1209                 : 
    1210                 : 
    1211               2 :                 kw = get_keyword (param1);
    1212               2 :                 switch (kw) {
    1213                 :                 case EKeywordRun:
    1214               1 :                         mip_get_next_string (params, &param2);
    1215               1 :                         mip_get_next_string (params, &param3);
    1216               1 :                         mip_get_next_string (params, &param4);
    1217                 :                         /* parsing is set to QuoteStyle, because test case
    1218                 :                          * title may contain whitespaces */
    1219               1 :                         parsing=mip_get_parsing_type (params);
    1220               1 :                         mip_set_parsing_type (params, EQuoteStyleParsing);
    1221                 :                         /* if title is specified, it's passed in here... */
    1222               1 :                         if(mip_get_next_string (params, &param5) == 0){
    1223               0 :                                 sprintf (extifmessage, "run module=%s "
    1224                 :                                      "testcasefile=%s testcasenum=%s "
    1225                 :                                      "testcasetitle=\"%s\"", param2,
    1226                 :                                      param3, param4, param5);
    1227                 :                         /* if it's not, id is used for compatibility */
    1228                 :                         } else { 
    1229               1 :                                 sprintf (extifmessage, "run module=%s "
    1230                 :                                      "testcasefile=%s testcasenum=%s", param2,
    1231                 :                                      param3, param4);
    1232                 :                         }
    1233               1 :                         mip_set_parsing_type (params, parsing);
    1234                 : 
    1235               1 :                         break;
    1236                 :                 case EKeywordSet:
    1237               0 :                         mip_get_next_string (params, &param2);
    1238               0 :                         sprintf (extifmessage, "set %s", param2);
    1239               0 :                         if (mip_get_next_string (params, &param3) == ENOERR)
    1240               0 :                                 sprintf (extifmessage + strlen (extifmessage),
    1241                 :                                          " type=%s", param3);
    1242               0 :                         break;
    1243                 :                 case EKeywordRequest:
    1244               0 :                         mip_get_next_string (params, &param2);
    1245               0 :                         sprintf (extifmessage, "request %s", param2);
    1246               0 :                         if (mip_get_next_string (params, &param3) == ENOERR)
    1247               0 :                                 sprintf (extifmessage + strlen (extifmessage),
    1248                 :                                          " type=%s", param3);
    1249               0 :                         break;
    1250                 :                 case EKeywordExpect:
    1251               1 :                         mip_get_next_string (params, &param2);
    1252               1 :                         tec_ms_handle_data_request (get_id_from_slavename
    1253                 :                                                     (message->message_),
    1254                 :                                                     param2, message->sender_);
    1255               1 :                         DELETE (extifmessage);
    1256               1 :                         return 0;
    1257                 :                         break;
    1258                 :                 case EKeywordRelease:
    1259                 :                 case EKeywordWait:
    1260                 :                 case EKeywordUnset:
    1261                 : 
    1262                 :                 default:
    1263               0 :                         strcpy (extifmessage, message->desc_);
    1264                 :                         break;
    1265                 :                 }
    1266               1 :                 send_to_slave (ERemoteSlave, message->message_, 0,
    1267                 :                                extifmessage);
    1268               1 :                 break;
    1269                 :         default:
    1270               0 :                 MIN_DEBUG ("MESSAGE: %s\n", message->message_);
    1271               0 :                 MIN_DEBUG ("DESC: %s\n", message->desc_);
    1272                 :                 break;
    1273                 :         }
    1274                 : 
    1275               5 :         DELETE (extifmessage);
    1276               5 :         DELETE (param1);
    1277               5 :         DELETE (param2);
    1278               5 :         DELETE (param3);
    1279               5 :         DELETE (param4);
    1280               5 :         DELETE (param5);
    1281               5 :         mip_destroy (&params);
    1282                 : 
    1283               5 :         return 0;
    1284                 : }
    1285                 : /* ------------------------------------------------------------------------- */
    1286                 : /** Function reads message received from external controller and 
    1287                 :  * calls  handling
    1288                 :  */
    1289                 : int tec_extif_message_received (char *message, int length)
    1290              12 : {
    1291              12 :         MinItemParser *extif_message = INITPTR;
    1292              12 :         int             result = 666;
    1293                 : 
    1294              12 :         MIN_DEBUG ("tec_extif_message_received: length %d", length);
    1295              12 :         MIN_DEBUG ("EXTIF SAYS: %s", message);
    1296              12 :         extif_message = mip_create (message, 0, length);
    1297              12 :         if (extif_message != INITPTR) {
    1298              12 :                 result = min_if_dispatch_extif_msg (extif_message);
    1299              11 :                 mip_destroy (&extif_message);
    1300                 :         } else {
    1301               0 :                 result = -1;
    1302               0 :                 MIN_WARN ("Could not create item parser object");
    1303                 :         }
    1304              11 :         MIN_DEBUG (" RETURNING: %d ", result);
    1305                 : 
    1306              11 :         return result;
    1307                 : }
    1308                 : /* ------------------------------------------------------------------------- */
    1309                 : /** Function that replaces "test case complete" callback, if min instance 
    1310                 :  * is used as slave.
    1311                 :  * @param run_id runtime id of test case (position in "selected cases" list)
    1312                 :  * @param execution_result indicates if starting of test case was successful
    1313                 :  * @param test_result result of test
    1314                 :  * @param desc description (taken from ipc message);
    1315                 :  */
    1316                 : void
    1317                 : master_report (int run_id, int execution_result, int test_result, char *desc)
    1318               0 : {
    1319               0 :         DLListIterator  finished_case_item = DLListNULLIterator;
    1320               0 :         DLListIterator  work_module_item = DLListNULLIterator;
    1321                 :         char           *extifmessage;
    1322                 : 
    1323               0 :         MIN_DEBUG ("MIN CALLBACK");
    1324                 :         /*let's get module pid from finished case */
    1325               0 :         finished_case_item = dl_list_at (selected_cases, run_id);
    1326               0 :         work_module_item = tc_get_test_module_ptr (finished_case_item);
    1327               0 :         extifmessage = NEW2 (char, 30);
    1328               0 :         sprintf (extifmessage, "remote run ready result=%d", test_result);
    1329               0 :         send_to_master (run_id + 1, extifmessage);
    1330                 : #ifdef MIN_EXTIF
    1331               0 :         original_complete_callback (run_id, execution_result, test_result,
    1332                 :                                     desc);
    1333                 : #endif
    1334                 : 
    1335                 :         /*Revert to "normal" external controller communincation if 
    1336                 :          * it is allowed, otherwise mark that it's allowed to revert. */
    1337               0 :         if (ok_to_break == ESTrue) {
    1338                 : #ifdef MIN_EXTIF
    1339               0 :                 MIN_DEBUG ("Restoring Callback");
    1340               0 :                 tfwif_callbacks.complete_callback_ = original_complete_callback;
    1341                 : #else
    1342                 :                 ;
    1343                 : #endif
    1344                 :         } else
    1345               0 :                 ok_to_break = ESTrue;
    1346               0 :         DELETE (extifmessage);
    1347               0 : }
    1348                 : /* ------------------------------------------------------------------------- */
    1349                 : /** Adds a new entry to pool of ip slaves
    1350                 :  *  @param he host address information
    1351                 :  *  @param slavetype type of the slave e.g. "phone"
    1352                 :  *  @return 0 on success, 1 on error
    1353                 :  */
    1354                 : int tec_add_ip_slave_to_pool (struct addrinfo **ai, char *slavetype)
    1355              16 : {
    1356                 :        slave_info *slave;
    1357                 :        DLListIterator it;
    1358                 :        
    1359              16 :        if (find_slave_by_addrinfo (*ai, &it) != INITPTR) {
    1360               0 :                MIN_WARN ("Slave already registered");
    1361               0 :                return 1;
    1362                 :        }
    1363              16 :        slave = NEW(slave_info);
    1364              16 :        slave->status_ = SLAVE_STAT_FREE;
    1365              16 :        slave->slave_id_ = 0;
    1366              16 :        slave->run_cnt_ = 0;
    1367              16 :        slave->addrinfo_ = *ai;
    1368              16 :        slave->slave_type_ = tx_create (slavetype);
    1369              16 :        slave->slave_name_ = INITPTR;
    1370              16 :        slave->fd_ = -1;
    1371              16 :        slave->write_queue_ = dl_list_create ();
    1372                 :        
    1373              16 :        dl_list_add (ms_assoc, slave);
    1374                 : 
    1375              16 :        return 0;
    1376                 : }
    1377                 : /* ------------------------------------------------------------------------- */
    1378                 : /** Deletes entry from the pool of ip slaves
    1379                 :  *  @param he host address information
    1380                 :  *  @param slavetype type of the slave e.g. "phone"
    1381                 :  *  @return 0 on success, 1 on error
    1382                 :  */
    1383                 : int tec_del_ip_slave_from_pool (struct addrinfo *ai, char *slavetype)
    1384               0 : {
    1385                 :        slave_info *slave;
    1386                 :        DLListIterator it;
    1387                 : 
    1388               0 :        if (ms_assoc == INITPTR)
    1389               0 :                return 1;
    1390                 :        
    1391               0 :        slave = find_slave_by_addrinfo (ai, &it); 
    1392               0 :        if (slave == INITPTR) {
    1393               0 :                MIN_WARN ("slave not found");
    1394               0 :                return 1;
    1395                 :        }
    1396                 :        
    1397               0 :        dl_list_remove_it (it);
    1398                 :        
    1399               0 :        if (slave->status_ & SLAVE_STAT_RESERVED) {
    1400               0 :                MIN_WARN ("slave still reserved");
    1401                 :        }
    1402                 : 
    1403               0 :        tx_destroy (&slave->slave_name_);
    1404               0 :        tx_destroy (&slave->slave_type_);
    1405                 : 
    1406                 :        /* FIXME flush write queue */
    1407                 : 
    1408               0 :        DELETE (slave);
    1409                 : 
    1410               0 :        return 0;
    1411                 : }
    1412                 : /* ------------------------------------------------------------------------- */
    1413                 : /** Used in tcp/ip operation to report case result to master
    1414                 :  * @param run_id runtime id of test case (position in "selected cases" list)
    1415                 :  * @param execution_result indicates if starting of test case was successful
    1416                 :  * @param test_result result of test
    1417                 :  * @param desc description (taken from ipc message);
    1418                 :  */
    1419                 : void
    1420                 : tcp_master_report (int run_id, int execution_result, int test_result, 
    1421                 :                    char *desc)
    1422               0 : {
    1423               0 :         DLListIterator  finished_case_item = DLListNULLIterator;
    1424               0 :         DLListIterator  work_module_item = DLListNULLIterator;
    1425                 :         char           *extifmessage;
    1426                 : 
    1427                 :         /*let's get module pid from finished case */
    1428               0 :         finished_case_item = dl_list_at (selected_cases, run_id);
    1429               0 :         work_module_item = tc_get_test_module_ptr (finished_case_item);
    1430               0 :         extifmessage = NEW2 (char, 30);
    1431               0 :         sprintf (extifmessage, "remote run ready result=%d", test_result);
    1432               0 :         send_to_master (run_id + 1, extifmessage);
    1433               0 :         DELETE (extifmessage);
    1434               0 : }
    1435                 : 
    1436                 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
    1437                 : #ifdef MIN_UNIT_TEST
    1438                 : 
    1439                 : 
    1440                 : #endif                          /* MIN_UNIT_TEST */
    1441                 : 
    1442                 : /* End of file */

Generated by: LTP GCOV extension version 1.6