/home/dko/projects/mobilec/trunk/src/agent.c

Go to the documentation of this file.
00001 /*[
00002  * Copyright (c) 2007 Integration Engineering Laboratory
00003                       University of California, Davis
00004  *
00005  * Permission to use, copy, and distribute this software and its
00006  * documentation for any purpose with or without fee is hereby granted,
00007  * provided that the above copyright notice appear in all copies and
00008  * that both that copyright notice and this permission notice appear
00009  * in supporting documentation.
00010  *
00011  * Permission to modify the software is granted, but not the right to
00012  * distribute the complete modified source code.  Modifications are to
00013  * be distributed as patches to the released version.  Permission to
00014  * distribute binaries produced by compiling modified sources is granted,
00015  * provided you
00016  *   1. distribute the corresponding source modifications from the
00017  *    released version in the form of a patch file along with the binaries,
00018  *   2. add special version identification to distinguish your version
00019  *    in addition to the base release version number,
00020  *   3. provide your name and address as the primary contact for the
00021  *    support of your modified version, and
00022  *   4. retain our contact information in regard to use of the base
00023  *    software.
00024  * Permission to distribute the released version of the source code along
00025  * with corresponding source modifications in the form of a patch file is
00026  * granted with same provisions 2 through 4 for binary distributions.
00027  *
00028  * This software is provided "as is" without express or implied warranty
00029  * to the extent permitted by applicable law.
00030 ]*/
00031 
00032 #ifndef _WIN32
00033 #include <unistd.h>
00034 #endif
00035 
00036 #include <embedch.h>
00037 
00038 #include "include/agent.h"
00039 #include "include/mc_platform.h"
00040 #include "include/message.h"
00041 #include "include/agent_lib.h"
00042 #include "include/agent_return_data.h"
00043 #include "include/xml_parser.h"
00044 
00045   agent_p
00046 agent_Copy(const agent_p agent)
00047 {
00048   agent_p cp_agent;
00049   cp_agent = (agent_p)malloc(sizeof(agent_t));
00050 
00051   MUTEX_LOCK(agent->lock);
00052   /* id */
00053   cp_agent->id = agent->id;
00054   /* name */
00055   cp_agent->name = (char*)malloc
00056     (
00057      sizeof(char) * 
00058      (strlen(agent->name) + 1)
00059     );
00060   strcpy(cp_agent->name, agent->name);
00061   /* connect_id: Not Needed */
00062   /* arrival_time */
00063   cp_agent->arrival_time = agent->arrival_time;
00064   /*owner*/
00065   cp_agent->owner = (char*)malloc
00066     (
00067      sizeof(char) * 
00068      (strlen(agent->owner) + 1)
00069     );
00070   strcpy(cp_agent->owner, agent->owner);
00071   /*home*/
00072   cp_agent->home = (char*)malloc
00073     (
00074      sizeof(char) * 
00075      (strlen(agent->home) + 1)
00076     );
00077   strcpy(cp_agent->home, agent->home);
00078   /*home_port*/
00079   cp_agent->home_port = agent->home_port;
00080   /*datastate*/
00081   cp_agent->datastate = agent_datastate_Copy(agent->datastate);
00082   /* Agent is an orphan */
00083   cp_agent->orphan = 1;
00084   /*agent_type*/
00085   cp_agent->agent_type = agent->agent_type;
00086   /*agent_status*/
00087   cp_agent->agent_status = agent->agent_status;
00088   /*return_data*/
00089   cp_agent->return_data = agent->return_data;
00090   /*agent_interp*/
00091   cp_agent->agent_interp = NULL;
00092   /*agent_thread*/
00093   cp_agent->agent_thread = NULL;
00094   /*run_lock*/
00095   cp_agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00096   MUTEX_INIT(cp_agent->run_lock);
00097   /*agent_persistent*/
00098   cp_agent->agent_persistent = agent->agent_persistent;
00099   
00100   /*lock*/
00101   cp_agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00102   MUTEX_INIT(cp_agent->lock);
00103 
00104   return cp_agent;
00105 }
00106 
00107 agent_p
00108 agent_New(void)
00109 {
00110   agent_p agent;
00111   agent = (agent_p)malloc(sizeof(agent_t));
00112   if(agent==NULL) {
00113     fprintf(stderr, "Memory error at %s:%d\n",
00114         __FILE__, __LINE__);
00115     return NULL;
00116   }
00117   /* Just init everything to zero */
00118   memset(agent, 0, sizeof(agent_t));
00119 
00120   /* Lets go ahead and allocate the threading stuff */
00121   MUTEX_NEW(agent->run_lock);
00122   MUTEX_INIT(agent->run_lock);
00123 
00124   MUTEX_NEW(agent->lock);
00125   MUTEX_INIT(agent->lock);
00126 
00127   return agent;
00128 }
00129 
00130   agent_p 
00131 agent_Initialize(
00132     struct mc_platform_s *mc_platform,
00133     message_p message,
00134     int id)
00135 {
00136   agent_p agent; 
00137   int err_code;
00138 
00139   /* malloc memory for the agent */
00140   agent = (MCAgent_t)malloc(sizeof(agent_t));
00141   memset(agent, 0, sizeof(agent_t));
00142 
00143   /* Set up general agent data access mutex */
00144   agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00145   MUTEX_INIT(agent->lock);
00146 
00147   /* Set up run_lock mutex */
00148   agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00149   MUTEX_INIT(agent->run_lock);
00150 
00151   /* set flags and variables for the agent */
00152   agent->id = id;
00153 #ifndef _WIN32
00154   agent->arrival_time = time(NULL);
00155 #else
00156   GetSystemTime( &(agent->arrival_time) );
00157 #endif
00158 
00159   /* set flags */
00160   agent->orphan = 0;
00161   agent->agent_script_ready = 1;
00162   agent->agent_pipe_ready_to_read = 0;
00163   agent->agent_ready_to_send = 0;
00164   agent->agent_pipe_active = 0;
00165 
00166   /* set the agent thread to null until activated */
00167   agent->agent_thread = NULL;
00168   agent->agent_thread_id = 0;
00169 
00170   /* Set up an empty mailbox */
00171   agent->mailbox = agent_mailbox_New();
00172 
00173   /* parse the xml */
00174   agent->datastate = agent_datastate_New();
00175   agent->datastate->xml_agent_root = message->xml_payload;
00176   agent->datastate->xml_root = message->xml_root;
00177   message->agent_xml_flag = 1;
00178   
00179   if (agent->datastate->xml_agent_root != NULL) {
00180     switch(message->message_type) {
00181       case MOBILE_AGENT:
00182         agent->agent_type = MC_REMOTE_AGENT;
00183         if( (err_code = agent_xml_parse(agent))) {
00184           fprintf(stderr, "error code %d. %s:%d\n",
00185               err_code, __FILE__, __LINE__ );
00186           agent_Destroy(agent);
00187           return NULL;
00188         }
00189         if (mc_platform->default_agentstatus != -1) {
00190           agent->agent_status = mc_platform->default_agentstatus;
00191         }
00192         break;
00193       case RETURN_MSG:
00194         agent->agent_type = MC_RETURN_AGENT;
00195         if( (err_code = agent_xml_parse(agent))) {
00196           fprintf(stderr, "error code %d. %s:%d\n",
00197               err_code, __FILE__, __LINE__ );
00198           agent_Destroy(agent);
00199           return NULL;
00200         }
00201         break;
00202       default:
00203         fprintf(stderr, "Invalid agent type: %d %s:%d\n",
00204             agent->agent_type, __FILE__, __LINE__ );
00205     }
00206   } else {
00207     mc_platform->err = MC_ERR_PARSE;
00208     /* Free up memory. */
00209     MUTEX_DESTROY(agent->lock);
00210     free(agent->lock);
00211     MUTEX_DESTROY(agent->run_lock);
00212     free(agent->run_lock);
00213 
00214     free(agent);
00215     return NULL;
00216   }
00217 
00218   /* In the future we will compare the current tasks server name to 
00219      the one on the server, presently this is not implemented */
00220 
00221   /* set the CH exectution flag */
00222   /* FIXME: This should be in the xml parser */
00223   /*if (agent->datastate->tasks[agent->datastate->task_progress]->init_agent_status != -1) {
00224     agent->agent_status = agent->datastate->tasks[agent->datastate->task_progress]->init_agent_status;
00225     } else {
00226     agent->agent_status = mc_platform->default_agentstatus;
00227     }
00228     */
00229   agent->agent_status = MC_WAIT_CH;
00230 
00231   agent->mc_platform = mc_platform;
00232 
00233   /* return */
00234   return agent;
00235 }
00236 
00237   int
00238 agent_Destroy(agent_p agent)
00239 {
00240   if (agent == NULL) {
00241     return MC_SUCCESS;
00242   }
00243   MUTEX_LOCK(agent->lock);
00244   if (agent->name != NULL) {
00245     free(agent->name);
00246   }
00247   if (agent->owner != NULL) {
00248     free(agent->owner);
00249   }
00250   if (agent->home != NULL) {
00251     free(agent->home);
00252   }
00253   /* Terminate the agent datastate memory */
00254   MUTEX_DESTROY(agent->lock);
00255   if (agent->agent_status == MC_AGENT_NEUTRAL) {
00256     if ((agent->agent_interp) != NULL) {
00257       Ch_End(agent->agent_interp);
00258     }
00259   }
00260   free(agent->lock);
00261   agent_datastate_Destroy(agent->datastate);
00262   free(agent->agent_thread);
00263   free(agent->run_lock);
00264   agent_mailbox_Destroy(agent->mailbox);
00265   /* deallocate the agent */
00266   free(agent);
00267   agent = NULL;
00268   return MC_SUCCESS;
00269 }
00270 
00271   extern void 
00272 agent_RunChScript(agent_p agent, mc_platform_p mc_platform)
00273 {
00274 #ifndef _WIN32
00275   pthread_attr_t attr;
00276   pthread_attr_init(&attr);
00277   if(mc_platform->stack_size[MC_THREAD_AGENT] != -1) {
00278     pthread_attr_setstacksize
00279       (
00280        &attr, 
00281        mc_platform->stack_size[MC_THREAD_AGENT]
00282       );
00283   }
00284   pthread_attr_setdetachstate /* Automatically reclaim thread memory for this thread */
00285     (
00286      &attr,
00287      PTHREAD_CREATE_DETACHED
00288     );
00289 #else
00290   int stack_size;
00291   if (mc_platform->stack_size[MC_THREAD_AGENT] < 1) {
00292           stack_size = mc_platform->stack_size[MC_THREAD_AGENT]+1;
00293   } else {
00294           stack_size = mc_platform->stack_size[MC_THREAD_AGENT];
00295   }
00296 #endif
00297   if(agent->agent_thread == NULL) 
00298   {
00299     agent->agent_thread = (THREAD_T *)malloc(sizeof(THREAD_T));
00300   }
00301 
00302   agent->agent_status = MC_AGENT_ACTIVE;
00303   agent->mc_platform = mc_platform;
00304 
00305   THREAD_CREATE(agent->agent_thread,
00306       agent_RunChScriptThread,
00307       agent );
00308 
00309   return;
00310 }
00311 
00312 #ifndef _WIN32
00313   void* 
00314 agent_RunChScriptThread(void * ChAgent)
00315 #else
00316   DWORD WINAPI 
00317 agent_RunChScriptThread(void* ChAgent)
00318 #endif
00319 {
00320 #ifndef _WIN32
00321   int fd;
00322 #endif
00323   MCAgent_t agent;
00324   mc_platform_p mc_platform;
00325   int n;
00326   FILE *TEMP_FILE;
00327   char *temp_store_file;
00328   char *ChShellArg[2];
00329   void *result;
00330   int progress;
00331   char *tmp_buf;
00332 
00333   /* set up the agent object */
00334   agent = (MCAgent_t)ChAgent;
00335   progress = agent->datastate->task_progress;
00336   mc_platform = agent->mc_platform;
00337 
00338   /* check to see if the agent is null */
00339   if(ChAgent == NULL)
00340   {
00341     printf("ERROR, AGENT NULL \n");
00342 #ifndef _WIN32
00343     return NULL;
00344 #else
00345     return 0;
00346 #endif
00347   }
00348   /* We need to check for custom interp_options. If any
00349    * value is null, then we pass null on to Ch_Initialize. */
00350   if( ((MCAgent_t)ChAgent)->mc_platform->interp_options == NULL ) {
00351 
00352     if(Ch_Initialize(&(((MCAgent_t)ChAgent)->agent_interp), 
00353           NULL))
00354     {
00355       printf("CH INIT ERROR \n");
00356       exit(EXIT_FAILURE);
00357     }
00358   } else {
00359     if(Ch_Initialize(&(((MCAgent_t)ChAgent)->agent_interp), 
00360           ((MCAgent_t)ChAgent)->mc_platform->interp_options))
00361     {
00362       printf("CH INIT ERROR \n");
00363       exit(EXIT_FAILURE);
00364     }
00365   }
00366 
00367   /* Declare special variables for holding the agent id and name */
00368   tmp_buf = malloc(sizeof(char) * 200);
00369   tmp_buf[0] = '\0';
00370   sprintf(tmp_buf, "int mc_agent_id=%d;", (int)agent->id);
00371   Ch_DeclareVar(
00372       agent->agent_interp,
00373       tmp_buf
00374       );
00375 
00376   tmp_buf[0] = '\0';
00377   sprintf(tmp_buf,
00378       "char mc_agent_name[]=\"%s\";",
00379       agent->name
00380       );
00381   Ch_DeclareVar(
00382       agent->agent_interp,
00383       tmp_buf
00384       );
00385 
00386   tmp_buf[0] = '\0';
00387   sprintf(tmp_buf, "void* mc_current_agent = (void*)%d;", (int)agent);
00388   Ch_DeclareVar(
00389       agent->agent_interp,
00390       tmp_buf
00391       );
00392 
00393   tmp_buf[0] = '\0';
00394   sprintf(tmp_buf, "char mc_host_name[] = \"%s\";",
00395       agent->mc_platform->hostname );
00396   Ch_DeclareVar(
00397       agent->agent_interp,
00398       tmp_buf
00399       );
00400 
00401   tmp_buf[0] = '\0';
00402   sprintf(tmp_buf, "int mc_host_port = %d;\n",
00403       agent->mc_platform->port );
00404   Ch_DeclareVar(
00405       agent->agent_interp,
00406       tmp_buf
00407       );
00408 
00409   tmp_buf[0] = '\0';
00410   sprintf(tmp_buf, "int mc_task_progress = %d;\n",
00411       agent->datastate->task_progress);
00412   Ch_DeclareVar(
00413       agent->agent_interp,
00414       tmp_buf
00415       );
00416 
00417   tmp_buf[0] = '\0';
00418   sprintf(tmp_buf, "int mc_num_tasks = %d;\n",
00419       agent->datastate->number_of_tasks );
00420   Ch_DeclareVar(
00421       agent->agent_interp,
00422       tmp_buf
00423       );
00424 
00425   /* Declare standard error code enum */
00426   tmp_buf[0] = '\0';
00427   sprintf(tmp_buf, "enum error_code_e {MC_SUCCESS = 0, MC_ERR, MC_ERR_CONNECT, MC_ERR_PARSE, MC_ERR_EMPTY, MC_ERR_INVALID, MC_ERR_INVALID_ARGS, MC_ERR_NOT_FOUND, MC_ERR_MEMORY, MC_ERR_SEND, MC_WARN_DUPLICATE };" );
00428   Ch_DeclareVar(
00429       agent->agent_interp,
00430       tmp_buf
00431       );
00432 
00433   tmp_buf[0] = '\0';
00434   sprintf(tmp_buf, "enum MC_SteerCommand_e {MC_RUN = 0, MC_SUSPEND, MC_RESTART, MC_STOP};" );
00435   Ch_DeclareVar(
00436       agent->agent_interp,
00437       tmp_buf
00438       );
00439 
00440   tmp_buf[0] = '\0';
00441   sprintf(tmp_buf, "enum mc_AgentStatus_e { MC_WAIT_CH, MC_WAIT_MESSGSEND, MC_AGENT_ACTIVE, MC_AGENT_NEUTRAL, MC_AGENT_SUSPENDED, MC_WAIT_FINISHED};"); 
00442   Ch_DeclareVar(
00443       agent->agent_interp,
00444       tmp_buf
00445       );
00446 
00447   free(tmp_buf);
00448   /* Add the MCAgent_t typedef */
00449   Ch_DeclareVar(
00450       agent->agent_interp,
00451       "void* MCAgent_t;"
00452       );
00453   Ch_DeclareTypedef(
00454       agent->agent_interp,
00455       "MCAgent_t"
00456       );
00457 
00458   /* Following are the declarations of the agent-space api functions. */
00459   Ch_DeclareFunc(
00460       agent->agent_interp,
00461       "int mc_AclDestroy(void* acl_message);",
00462       (ChFuncdl_t)MC_AclDestroy_chdl
00463       );
00464   Ch_DeclareFunc(
00465       agent->agent_interp,
00466       "void* mc_AclNew(void);",
00467       (ChFuncdl_t)MC_AclNew_chdl
00468       );
00469   Ch_DeclareFunc(
00470       agent->agent_interp,
00471       "void* mc_AclPost(void* agent, void* acl_message);",
00472       (ChFuncdl_t)MC_AclPost_chdl
00473       );
00474   Ch_DeclareFunc(
00475       agent->agent_interp,
00476       "void* mc_AclRetrieve(void* agent);",
00477       (ChFuncdl_t)MC_AclRetrieve_chdl
00478       );
00479   Ch_DeclareFunc(
00480       agent->agent_interp,
00481       "void* mc_AclReply(void* acl_message);",
00482       (ChFuncdl_t)MC_AclReply_chdl
00483       );
00484   Ch_DeclareFunc(
00485       agent->agent_interp,
00486       "int mc_AclSend(void* acl_message);",
00487       (ChFuncdl_t)MC_AclSend_chdl
00488       );
00489   Ch_DeclareFunc(
00490       agent->agent_interp,
00491       "void* mc_AclWaitRetrieve(void* agent);",
00492       (ChFuncdl_t)MC_AclWaitRetrieve_chdl
00493       );
00494   /* begin Acl Helper Functions */
00495   Ch_DeclareFunc(
00496       agent->agent_interp,
00497       "int mc_Acl_SetPerformative(void* acl_message, int performative);",
00498       (ChFuncdl_t)MC_Acl_SetPerformative_chdl
00499       );
00500   Ch_DeclareFunc(
00501       agent->agent_interp,
00502       "int mc_Acl_SetSender(void* acl_message, char* name, char* address);",
00503       (ChFuncdl_t)MC_Acl_SetSender_chdl
00504       );
00505   Ch_DeclareFunc(
00506       agent->agent_interp,
00507       "int mc_Acl_AddReceiver(void* acl_message, char* name, char* address);",
00508       (ChFuncdl_t)MC_Acl_AddReceiver_chdl
00509       );
00510   Ch_DeclareFunc(
00511       agent->agent_interp,
00512       "int mc_Acl_AddReplyTo(void* acl_message, char* name, char* address);",
00513       (ChFuncdl_t)MC_Acl_AddReplyTo_chdl
00514       );
00515   Ch_DeclareFunc(
00516       agent->agent_interp,
00517       "int mc_Acl_SetContent(void* acl_message, char* content);",
00518       (ChFuncdl_t)MC_Acl_SetContent_chdl
00519       );
00520   /* end Acl Helper Functions */
00521   Ch_DeclareFunc(
00522       agent->agent_interp,
00523       "int mc_AddAgent(void* agent);",
00524       (ChFuncdl_t)MC_AddAgent_chdl
00525       );
00526   Ch_DeclareFunc(
00527       agent->agent_interp,
00528       "int mc_Barrier(int id);",
00529       (ChFuncdl_t)MC_Barrier_chdl
00530       );
00531   Ch_DeclareFunc(
00532       agent->agent_interp,
00533       "int mc_BarrierDelete(int id);",
00534       (ChFuncdl_t)MC_BarrierDelete_chdl
00535       );
00536   Ch_DeclareFunc(
00537       agent->agent_interp,
00538       "int mc_BarrierInit(int id, int num_procs);",
00539       (ChFuncdl_t)MC_BarrierInit_chdl
00540       );
00541   Ch_DeclareFunc(
00542       agent->agent_interp,
00543       "int mc_CallAgentFunc(MCAgent_t agent, const char* funcName, void* returnVal, void* arg_struct);",
00544       (ChFuncdl_t)MC_CallAgentFunc_chdl
00545       );
00546   Ch_DeclareFunc(
00547       agent->agent_interp,
00548       "MCAgent_t mc_ComposeAgent(const char* name, *home, *owner, *code, *return_var_name, *server, int persistent);",
00549       (ChFuncdl_t)MC_ComposeAgent_chdl
00550       );
00551   Ch_DeclareFunc(
00552       agent->agent_interp,
00553       "int mc_CondBroadcast(int id);",
00554       (ChFuncdl_t)MC_CondBroadcast_chdl
00555       );
00556   Ch_DeclareFunc(
00557       agent->agent_interp,
00558       "int mc_CondSignal(int id);",
00559       (ChFuncdl_t)MC_CondSignal_chdl
00560       );
00561   Ch_DeclareFunc(
00562       agent->agent_interp,
00563       "int mc_CondReset(int id);",
00564       (ChFuncdl_t)MC_CondReset_chdl 
00565       );
00566   Ch_DeclareFunc(
00567       agent->agent_interp,
00568       "int mc_CondWait(int id);",
00569       (ChFuncdl_t)MC_CondWait_chdl 
00570       );
00571   Ch_DeclareFunc(
00572       agent->agent_interp,
00573       "int mc_DeleteAgent(MCAgent_t agent);",
00574       (ChFuncdl_t)MC_DeleteAgent_chdl 
00575       );
00576   Ch_DeclareFunc(
00577       agent->agent_interp,
00578       "int mc_DeregisterService(int agentID, char* serviceName);",
00579       (ChFuncdl_t)MC_DeregisterService_chdl
00580       );
00581   Ch_DeclareFunc(
00582       agent->agent_interp,
00583       "int mc_DestroyServiceSearchResult( char** agentName, char** serviceName, int* agentID, int numResult);",
00584       (ChFuncdl_t)MC_DestroyServiceSearchResult_chdl 
00585       );
00586   Ch_DeclareFunc(
00587       agent->agent_interp,
00588       "int mc_End(void);",
00589       (ChFuncdl_t)MC_End_chdl
00590       );
00591   Ch_DeclareFunc(
00592       agent->agent_interp,
00593       "void *mc_FindAgentByID(int id);",
00594       (ChFuncdl_t)MC_FindAgentByID_chdl
00595       );
00596   Ch_DeclareFunc(
00597       agent->agent_interp,
00598       "void *mc_FindAgentByName(const char *name);",
00599       (ChFuncdl_t)MC_FindAgentByName_chdl
00600       );
00601   /* FIXME -- This block of code does not work: Ch does not
00602    * understand 'time_t' */
00603   /*
00604   Ch_DeclareFunc(
00605       agent->agent_interp,
00606       "time_t mc_GetAgentArrivalTime(void* agent);",
00607       (ChFuncdl_t)MC_GetAgentArrivalTime_chdl
00608       );
00609       */
00610   Ch_DeclareFunc(
00611       agent->agent_interp,
00612       "int MC_GetAgentID(void* agent);",
00613       (ChFuncdl_t)MC_GetAgentStatus_chdl
00614       );
00615   Ch_DeclareFunc(
00616       agent->agent_interp,
00617       "char* MC_GetAgentName(void* agent);",
00618       (ChFuncdl_t)MC_GetAgentStatus_chdl
00619       );
00620   Ch_DeclareFunc(
00621       agent->agent_interp,
00622       "int mc_GetAgentStatus(void* agent);",
00623       (ChFuncdl_t)MC_GetAgentStatus_chdl
00624       );
00625   Ch_DeclareFunc(
00626       agent->agent_interp,
00627       "char *mc_GetAgentXMLString(void* agent);",
00628       (ChFuncdl_t)MC_GetAgentXMLString_chdl
00629       );
00630 
00631 #ifndef _WIN32
00632   Ch_DeclareFunc(
00633       agent->agent_interp,
00634       "int mc_gettimeofday(void* tv);",
00635       (ChFuncdl_t)MC_GetTimeOfDay_chdl
00636       );
00637 #endif
00638 
00639   Ch_DeclareFunc(
00640       agent->agent_interp,
00641       "int mc_HaltAgency(void);",
00642       (ChFuncdl_t)MC_HaltAgency_chdl
00643       );
00644   Ch_DeclareFunc(
00645       agent->agent_interp,
00646       "int mc_MutexLock(int id);",
00647       (ChFuncdl_t)MC_MutexLock_chdl
00648       );
00649   Ch_DeclareFunc(
00650       agent->agent_interp,
00651       "int mc_MutexUnlock(int id);",
00652       (ChFuncdl_t)MC_MutexUnlock_chdl
00653       );
00654   Ch_DeclareFunc(
00655       agent->agent_interp,
00656       "int mc_PrintAgentCode(void* agent);",
00657       (ChFuncdl_t)MC_PrintAgentCode_chdl
00658       );
00659   Ch_DeclareFunc(
00660       agent->agent_interp,
00661       "int mc_ResumeAgency(void);",
00662       (ChFuncdl_t)MC_ResumeAgency_chdl
00663       );
00664   Ch_DeclareFunc(
00665       agent->agent_interp,
00666       "int mc_SearchForService(const char* searchString, char*** agentNames, char*** serviceNames, int** agentIDs, int* numResults);",
00667       (ChFuncdl_t)MC_SearchForService_chdl
00668       );
00669   Ch_DeclareFunc(
00670       agent->agent_interp,
00671       "int mc_SendSteerCommand(enum MC_SteerCommand_e command);",
00672       (ChFuncdl_t)MC_SendSteerCommand_chdl
00673       );
00674   Ch_DeclareFunc(
00675       agent->agent_interp,
00676       "int mc_RegisterService(MCAgent_t agent, char **serviceNames, int numServices);",
00677       (ChFuncdl_t)MC_RegisterService_chdl
00678       );
00679   Ch_DeclareFunc(
00680       agent->agent_interp,
00681       "void *mc_RetrieveAgent(void);",
00682       (ChFuncdl_t)MC_RetrieveAgent_chdl
00683       );
00684   Ch_DeclareFunc(
00685       agent->agent_interp,
00686       "char *mc_RetrieveAgentCode(void* agent);",
00687       (ChFuncdl_t)MC_RetrieveAgentCode_chdl
00688       );
00689   Ch_DeclareFunc(
00690       agent->agent_interp,
00691       "int mc_SemaphoreWait(int id);",
00692       (ChFuncdl_t)MC_SemaphoreWait_chdl
00693       );
00694   Ch_DeclareFunc(
00695       agent->agent_interp,
00696       "int mc_SemaphorePost(int id);",
00697       (ChFuncdl_t)MC_SemaphorePost_chdl
00698       );
00699   Ch_DeclareFunc(
00700       agent->agent_interp,
00701       "int mc_SendAgentMigrationMessage(char *message, char *hostname, int port);",
00702       (ChFuncdl_t)MC_SendAgentMigrationMessage_chdl
00703       );
00704   Ch_DeclareFunc(
00705       agent->agent_interp,
00706       "int mc_SendAgentMigrationMessageFile(char *filename, char *hostname, int port);",
00707       (ChFuncdl_t)MC_SendAgentMigrationMessageFile_chdl
00708       );
00709   Ch_DeclareFunc(
00710       agent->agent_interp,
00711       "int mc_SetAgentStatus(void* agent, int status);",
00712       (ChFuncdl_t)MC_SetAgentStatus_chdl
00713       );
00714   Ch_DeclareFunc(
00715       agent->agent_interp,
00716       "int mc_SetDefaultAgentStatus(int status);",
00717       (ChFuncdl_t)MC_SetDefaultAgentStatus_chdl
00718       );
00719   Ch_DeclareFunc(
00720       agent->agent_interp,
00721       "int mc_SyncDelete(int id);",
00722       (ChFuncdl_t)MC_SyncDelete_chdl 
00723       );
00724   Ch_DeclareFunc(
00725       agent->agent_interp,
00726       "int mc_SyncInit(int id);",
00727       (ChFuncdl_t)MC_SyncInit_chdl 
00728       );
00729   Ch_DeclareFunc(
00730       agent->agent_interp,
00731       "int mc_TerminateAgent(void* agent);",
00732       (ChFuncdl_t)MC_TerminateAgent_chdl
00733       );
00734   Ch_DeclareFunc(
00735       agent->agent_interp,
00736       "int mc_GetAgentID(void* agent);",
00737       (ChFuncdl_t)MC_GetAgentID_chdl
00738       );
00739   Ch_DeclareFunc(
00740       agent->agent_interp,
00741       "char *mc_GetAgentName(void* agent);",
00742       (ChFuncdl_t)MC_GetAgentName_chdl
00743       );
00744   /* Originally, we hope to use append runscript if the buffer for code is less than 5120 bytes.
00745      Otherwise we must open a file and save the data to the filename.
00746      However, since the mobile agent codes for testing are complete programs 
00747      which contain preprocessing directives like "#include" and are larger than 51 bytes, we use
00748      the following statement to save the data to a file instead of putting it into the buffer. 
00749 
00750 FIXME: This is silly
00751 */
00752   if(strlen(agent->datastate->agent_code) < 51)
00753   {
00754     if(Ch_AppendRunScript(
00755           ((MCAgent_t)ChAgent)->agent_interp, 
00756           ((MCAgent_t)ChAgent)->datastate->agent_code))
00757     {
00758       printf("CH Failure \n");
00759       exit(EXIT_FAILURE);
00760     }
00761     if(Ch_CallFuncByName(((MCAgent_t)ChAgent)->agent_interp, "main", NULL))
00762     {
00763       printf("CH2 failure \n");
00764       exit(EXIT_FAILURE);
00765     }
00766   }
00767   else
00768   {
00769     /* save the agent to an external file %agentname%%d%d */
00770     temp_store_file = (char *)malloc(sizeof(char)*30);
00771 
00772 #ifndef _WIN32
00773     strcpy(temp_store_file, "agentchscriptXXXXXX");
00774     fd = mkstemp(temp_store_file);
00775     if (fd == -1) {
00776       fprintf(stderr, "Could not create temporary file:%s. %s:%d\n",
00777           temp_store_file,
00778           __FILE__,
00779           __LINE__ );
00780       exit(EXIT_FAILURE);
00781     }
00782     close(fd);
00783 #else
00784     tmpnam(temp_store_file);
00785 #endif
00786     TEMP_FILE = fopen(temp_store_file, "w");
00787     
00788     /* write the data to a ch-file */
00789     n = fwrite(
00790         (void *)agent->datastate->agent_code, 
00791         sizeof(char), 
00792         strlen(agent->datastate->agent_code), 
00793         TEMP_FILE);
00794 
00795     fclose(TEMP_FILE);
00796 
00797     /* set the Ch Shell arguments as appropriate */
00798     ChShellArg[0] = temp_store_file;
00799     ChShellArg[1] = NULL;
00800     MUTEX_LOCK(agent->run_lock);
00801     Ch_RunScript(agent->agent_interp, ChShellArg); 
00802     MUTEX_UNLOCK(agent->run_lock);
00803 
00804     /*        if(Ch_CallFuncByName(((MCAgent_t)ChAgent)->agent_interp, "main", NULL))
00805               {
00806               printf("CH2 failure \n");
00807               exit(EXIT_FAILURE);
00808               } */
00809 
00810     /* remove the temp file after its usage */
00811     remove(temp_store_file);
00812     free(temp_store_file);
00813   }
00814 
00815   /* now add the data element returned from the Ch execution into the agent data structure */
00816   if(strcmp(agent->datastate->tasks[progress]->var_name, "no-return"))
00817   {
00818     result = agent_return_data_InitializeFromAgent(agent);
00819     /* Free old result extracted from XML agent */
00820     agent_return_data_Destroy(
00821         agent->datastate->tasks[progress]->agent_return_data
00822         );
00823     /* Replace with new freshly calculated one */
00824     agent->datastate->tasks[progress]->agent_return_data = 
00825       result;
00826   } else {
00827     agent_return_data_Destroy(
00828         agent->datastate->tasks[progress]->agent_return_data );
00829     agent->datastate->tasks[progress]->agent_return_data = NULL;
00830   }
00831 
00832   if (agent->datastate->persistent || 
00833       agent->datastate->tasks[progress]->persistent ) {
00834     /* TODO: We need a large while loop here that waits on a condition 
00835        variable. Upon waking up, we will need to check a 'mailbox' for
00836        a struct containing
00837        1. A message/command
00838        2. A void* to generic data
00839        3. The size of the data.
00840        It should then execute the command, and check to see if the
00841        persistent flag is still set. If it is, loop again. 
00842        */
00843     /* For now, let us just not end the Ch interpreter and set the 
00844      * agent_status to MC_AGENT_NEUTRAL to cause it to hang. */
00845     ((MCAgent_t) ChAgent)->agent_status = MC_AGENT_NEUTRAL;
00846   } else {
00847     if ((((MCAgent_t)ChAgent)->agent_interp) != NULL) {
00848       Ch_End(((MCAgent_t)ChAgent)->agent_interp);
00849     }
00850     if (
00851         (agent->datastate->
00852          tasks[progress]->agent_return_data == NULL) &&
00853         (agent->datastate->task_progress ==
00854          (agent->datastate->number_of_tasks-1))
00855        ) 
00856     {
00857       ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_FINISHED;
00858     }
00859     else {
00860       ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_MESSGSEND; 
00861     }
00862   }
00863 
00864   /* close the task, indicating that it has been completed */
00865   agent->datastate->
00866     tasks[agent->datastate->task_progress]->task_completed = 1;
00867   agent->datastate->task_progress++;
00868 
00869   if (
00870       (agent->datastate->task_progress >= agent->datastate->number_of_tasks)
00871      )
00872   {
00873     agent->agent_type = MC_RETURN_AGENT;
00874   }
00875 
00876   SIGNAL(
00877       mc_platform->MC_signal_cond,
00878       mc_platform->MC_signal_lock,
00879       mc_platform->MC_signal = MC_EXEC_AGENT;
00880       );
00881 
00882   MUTEX_LOCK( mc_platform->MC_signal_lock);
00883   MUTEX_UNLOCK( mc_platform->MC_signal_lock );
00884   MUTEX_LOCK(mc_platform->ams->runflag_lock);
00885   mc_platform->ams->run = 1;
00886   COND_SIGNAL(mc_platform->ams->runflag_cond);
00887   MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
00888 
00889 #ifndef _WIN32
00890   pthread_exit(ChAgent);  
00891 #else
00892   return 0;
00893 #endif
00894 }
00895 
00896 

Generated on Fri May 16 14:49:54 2008 for Mobile-C by  doxygen 1.5.4