00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _WIN32
00036 #include <unistd.h>
00037 #include "config.h"
00038 #else
00039 #include "winconfig.h"
00040 #endif
00041
00042 #include <embedch.h>
00043
00044 #include "include/libmc.h"
00045 #include "include/agent.h"
00046 #include "include/mc_platform.h"
00047 #include "include/message.h"
00048 #include "include/agent_lib.h"
00049 #include "include/interpreter_variable_data.h"
00050 #include "include/xml_parser.h"
00051 #include "include/fipa_acl.h"
00052
00053 int agent_AddPersistentVariable(agent_p agent, int task_num, const char* var_name)
00054 {
00055 int i;
00056 int size;
00057 int data_type_size;
00058 int progress;
00059 interpreter_variable_data_t *agent_variable_data;
00060 interpreter_variable_data_t *tmp;
00061 agent_variable_data = (interpreter_variable_data_t*)malloc(sizeof(interpreter_variable_data_t));
00062 agent_variable_data->name = strdup(var_name);
00063
00064
00065 agent_variable_data->data_type = Ch_DataType(
00066 *agent->agent_interp,
00067 var_name );
00068
00069 if (agent_variable_data->data_type == CH_UNDEFINETYPE) {
00070 free(agent_variable_data);
00071 fprintf(stderr, "Warning: agent %s attempted saving of invalid variable, %s. %s:%d\n",
00072 agent->name, var_name, __FILE__, __LINE__);
00073 return MC_ERR;
00074 }
00075
00076 agent_variable_data->array_dim = Ch_ArrayDim(
00077 *agent->agent_interp,
00078 var_name );
00079
00080 agent_variable_data->array_extent = (int*)malloc(
00081 sizeof(int) * agent_variable_data->array_dim );
00082 for (i=0; i<agent_variable_data->array_dim; i++) {
00083 agent_variable_data->array_extent[i] =
00084 Ch_ArrayExtent(
00085 *agent->agent_interp,
00086 var_name,
00087 i );
00088 }
00089
00090 size = 1;
00091 for (i=0; i < agent_variable_data->array_dim; i++) {
00092 size *= agent_variable_data->array_extent[i];
00093 }
00094
00095
00096 CH_DATATYPE_SIZE(agent_variable_data->data_type, data_type_size);
00097
00098 agent_variable_data->data = (void*)malloc(size * data_type_size);
00099 CHECK_NULL(agent_variable_data->data, exit(0));
00100
00101
00102 progress = agent->datastate->task_progress;
00103 i = 0;
00104
00105 if (agent_variable_data->array_dim == 0) {
00106 memcpy(
00107 agent_variable_data->data,
00108 (void*)Ch_GlobalSymbolAddrByName(
00109 *agent->agent_interp,
00110 var_name),
00111 size*data_type_size
00112 );
00113
00114 } else {
00115 memcpy(
00116 agent_variable_data->data,
00117 (void*)Ch_GlobalSymbolAddrByName(
00118 *agent->agent_interp,
00119 var_name),
00120 size*data_type_size
00121 );
00122 }
00123 agent_variable_data->size = size*data_type_size;
00124
00125
00126 ListWRLock(agent->datastate->tasks[task_num]->agent_variable_list);
00127 tmp = (interpreter_variable_data_t*)ListDeleteCB(
00128 agent->datastate->tasks[task_num]->agent_variable_list,
00129 var_name,
00130 (ListSearchFunc_t)interpreter_variable_data_CmpName);
00131 if(tmp) interpreter_variable_data_Destroy(tmp);
00132 ListAdd(
00133 agent->datastate->tasks[task_num]->agent_variable_list,
00134 agent_variable_data);
00135 ListWRUnlock(agent->datastate->tasks[task_num]->agent_variable_list);
00136 return 0;
00137 }
00138
00139 agent_p
00140 agent_Copy(const agent_p agent)
00141 {
00142 agent_p cp_agent;
00143 cp_agent = agent_New();
00144
00145 MUTEX_LOCK(agent->lock);
00146
00147 cp_agent->id = agent->id;
00148
00149 cp_agent->name = (char*)malloc
00150 (
00151 sizeof(char) *
00152 (strlen(agent->name) + 1)
00153 );
00154 strcpy(cp_agent->name, agent->name);
00155
00156
00157 cp_agent->arrival_time = agent->arrival_time;
00158
00159 cp_agent->owner = (char*)malloc
00160 (
00161 sizeof(char) *
00162 (strlen(agent->owner) + 1)
00163 );
00164 strcpy(cp_agent->owner, agent->owner);
00165
00166 cp_agent->home = (char*)malloc
00167 (
00168 sizeof(char) *
00169 (strlen(agent->home) + 1)
00170 );
00171 strcpy(cp_agent->home, agent->home);
00172
00173 cp_agent->home_port = agent->home_port;
00174
00175 cp_agent->datastate = agent_datastate_Copy(agent->datastate);
00176
00177 cp_agent->orphan = 1;
00178
00179 cp_agent->agent_type = agent->agent_type;
00180
00181 cp_agent->agent_status = agent->agent_status;
00182
00183 cp_agent->return_data = agent->return_data;
00184
00185 cp_agent->agent_interp = NULL;
00186
00187 cp_agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00188 MUTEX_INIT(cp_agent->run_lock);
00189
00190 cp_agent->agent_persistent = agent->agent_persistent;
00191
00192
00193 cp_agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00194 MUTEX_INIT(cp_agent->lock);
00195 MUTEX_NEW(cp_agent->agent_status_lock);
00196 MUTEX_INIT(cp_agent->agent_status_lock);
00197 COND_NEW(cp_agent->agent_status_cond);
00198 COND_INIT(cp_agent->agent_status_cond);
00199
00200
00201 cp_agent->mailbox = ListInitialize();
00202
00203 return cp_agent;
00204 }
00205
00206 agent_p
00207 agent_New(void)
00208 {
00209 agent_p agent;
00210 agent = (agent_p)malloc(sizeof(agent_t));
00211 if(agent==NULL) {
00212 fprintf(stderr, "Memory error at %s:%d\n",
00213 __FILE__, __LINE__);
00214 return NULL;
00215 }
00216
00217 memset(agent, 0, sizeof(agent_t));
00218
00219
00220 MUTEX_NEW(agent->run_lock);
00221 MUTEX_INIT(agent->run_lock);
00222
00223 MUTEX_NEW(agent->lock);
00224 MUTEX_INIT(agent->lock);
00225
00226 MUTEX_NEW(agent->agent_status_lock);
00227 MUTEX_INIT(agent->agent_status_lock);
00228 COND_NEW(agent->agent_status_cond);
00229 COND_INIT(agent->agent_status_cond);
00230
00231 agent->mailbox = ListInitialize();
00232
00233 return agent;
00234 }
00235
00236 agent_p
00237 agent_NewBinary( struct mc_platform_s *mc_platform)
00238 {
00239 agent_p agent;
00240
00241
00242 agent = (MCAgent_t)malloc(sizeof(agent_t));
00243 memset(agent, 0, sizeof(agent_t));
00244
00245
00246 agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00247 MUTEX_INIT(agent->lock);
00248
00249
00250 MUTEX_NEW(agent->agent_status_lock);
00251 MUTEX_INIT(agent->agent_status_lock);
00252 COND_NEW(agent->agent_status_cond);
00253 COND_INIT(agent->agent_status_cond);
00254
00255
00256 agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00257 MUTEX_INIT(agent->run_lock);
00258
00259
00260 agent->id = rand();
00261 #ifndef _WIN32
00262 agent->arrival_time = time(NULL);
00263 #else
00264 GetSystemTime( &(agent->arrival_time) );
00265 #endif
00266
00267 agent->home = NULL;
00268 agent->sender = NULL;
00269
00270
00271 agent->orphan = 0;
00272 agent->agent_script_ready = 1;
00273 agent->agent_pipe_ready_to_read = 0;
00274 agent->agent_ready_to_send = 0;
00275 agent->agent_pipe_active = 0;
00276 agent->binary = 1;
00277
00278
00279 agent->agent_thread_id = 0;
00280
00281
00282 agent->mailbox = ListInitialize();
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 MUTEX_LOCK(agent->agent_status_lock);
00296 agent->agent_status = MC_AGENT_ACTIVE;
00297 COND_BROADCAST(agent->agent_status_cond);
00298 MUTEX_UNLOCK(agent->agent_status_lock);
00299
00300 agent->mc_platform = mc_platform;
00301
00302 agent->agent_address = (char*)malloc(sizeof(char) *
00303 (strlen(agent->mc_platform->hostname) + 12 + 10)
00304 );
00305 if (agent->agent_address == NULL) {
00306 fprintf(stderr, "Memory error. %s:%d\n", __FILE__, __LINE__);
00307 exit(-1);
00308 }
00309 sprintf(agent->agent_address,
00310 "http://%s:%d/acc",
00311 agent->mc_platform->hostname,
00312 agent->mc_platform->port
00313 );
00314
00315 return agent;
00316 }
00317 agent_p
00318 agent_Initialize(
00319 struct mc_platform_s *mc_platform,
00320 message_p message,
00321 int id)
00322 {
00323 agent_p agent;
00324 int err_code;
00325
00326
00327 agent = (MCAgent_t)malloc(sizeof(agent_t));
00328 memset(agent, 0, sizeof(agent_t));
00329
00330
00331 agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00332 MUTEX_INIT(agent->lock);
00333
00334
00335 MUTEX_NEW(agent->agent_status_lock);
00336 MUTEX_INIT(agent->agent_status_lock);
00337 COND_NEW(agent->agent_status_cond);
00338 COND_INIT(agent->agent_status_cond);
00339
00340
00341 agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00342 MUTEX_INIT(agent->run_lock);
00343
00344
00345 agent->id = id;
00346 #ifndef _WIN32
00347 agent->arrival_time = time(NULL);
00348 #else
00349 GetSystemTime( &(agent->arrival_time) );
00350 #endif
00351
00352 agent->home = NULL;
00353 agent->sender = NULL;
00354
00355
00356 agent->orphan = 0;
00357 agent->agent_script_ready = 1;
00358 agent->agent_pipe_ready_to_read = 0;
00359 agent->agent_ready_to_send = 0;
00360 agent->agent_pipe_active = 0;
00361
00362
00363 agent->agent_thread_id = 0;
00364
00365
00366 agent->mailbox = ListInitialize();
00367
00368
00369 agent->datastate = agent_datastate_New();
00370 agent->datastate->xml_agent_root = message->xml_payload;
00371 agent->datastate->xml_root = message->xml_root;
00372 message->agent_xml_flag = 1;
00373
00374 if (agent->datastate->xml_agent_root != NULL) {
00375 switch(message->message_type) {
00376 case MOBILE_AGENT:
00377 agent->agent_type = MC_REMOTE_AGENT;
00378 if( (err_code = agent_xml_parse(agent))) {
00379 fprintf(stderr, "error code %d. %s:%d\n",
00380 err_code, __FILE__, __LINE__ );
00381 agent_Destroy(agent);
00382 return NULL;
00383 }
00384 if (mc_platform->default_agentstatus != -1) {
00385 MUTEX_LOCK(agent->agent_status_lock);
00386 agent->agent_status = (enum MC_AgentStatus_e)mc_platform->default_agentstatus;
00387 COND_BROADCAST(agent->agent_status_cond);
00388 MUTEX_UNLOCK(agent->agent_status_lock);
00389 }
00390 break;
00391 case RETURN_MSG:
00392 agent->agent_type = MC_RETURN_AGENT;
00393 if( (err_code = agent_xml_parse(agent))) {
00394 fprintf(stderr, "error code %d. %s:%d\n",
00395 err_code, __FILE__, __LINE__ );
00396 agent_Destroy(agent);
00397 return NULL;
00398 }
00399 break;
00400 default:
00401 fprintf(stderr, "Invalid agent type: %d %s:%d\n",
00402 agent->agent_type, __FILE__, __LINE__ );
00403 }
00404 } else {
00405 mc_platform->err = MC_ERR_PARSE;
00406
00407 MUTEX_DESTROY(agent->lock);
00408 free(agent->lock);
00409 MUTEX_DESTROY(agent->run_lock);
00410 free(agent->run_lock);
00411 MUTEX_DESTROY(agent->agent_status_lock);
00412 free(agent->agent_status_lock);
00413 COND_DESTROY(agent->agent_status_cond);
00414 free(agent->agent_status_cond);
00415
00416 free(agent);
00417 return NULL;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 MUTEX_LOCK(agent->agent_status_lock);
00432 agent->agent_status = MC_WAIT_CH;
00433 COND_BROADCAST(agent->agent_status_cond);
00434 MUTEX_UNLOCK(agent->agent_status_lock);
00435
00436 agent->mc_platform = mc_platform;
00437
00438 agent->agent_address = (char*)malloc(sizeof(char) *
00439 (strlen(agent->mc_platform->hostname) + 12 + 10)
00440 );
00441 if (agent->agent_address == NULL) {
00442 fprintf(stderr, "Memory error. %s:%d\n", __FILE__, __LINE__);
00443 exit(-1);
00444 }
00445 sprintf(agent->agent_address,
00446 "http://%s:%d/acc",
00447 agent->mc_platform->hostname,
00448 agent->mc_platform->port
00449 );
00450
00451 return agent;
00452 }
00453
00454 int
00455 agent_Destroy(agent_p agent)
00456 {
00457 if (agent == NULL) {
00458 return MC_SUCCESS;
00459 }
00460 MUTEX_LOCK(agent->lock);
00461 if (agent->name != NULL) {
00462 free(agent->name);
00463 }
00464 if (agent->owner != NULL) {
00465 free(agent->owner);
00466 }
00467 if (agent->home != NULL) {
00468 free(agent->home);
00469 }
00470 if (agent->sender != NULL) {
00471 free(agent->sender);
00472 }
00473 if (agent->wg_code != NULL) {
00474 free(agent->wg_code);
00475 }
00476 if (agent->agent_address != NULL) {
00477 free(agent->agent_address);
00478 }
00479
00480 MUTEX_LOCK(agent->agent_status_lock);
00481 if (agent->agent_status == MC_AGENT_NEUTRAL) {
00482 MUTEX_UNLOCK(agent->agent_status_lock);
00483 if ((agent->agent_interp) != NULL) {
00484 Ch_Reset(*agent->agent_interp);
00485 ListWRLock(agent->mc_platform->interpreter_queue);
00486 ListAdd(agent->mc_platform->interpreter_queue, agent->agent_interp);
00487 ListWRUnlock(agent->mc_platform->interpreter_queue);
00488 }
00489 } else {
00490 MUTEX_UNLOCK(agent->agent_status_lock);
00491 }
00492 MUTEX_DESTROY(agent->agent_status_lock);
00493 free(agent->agent_status_lock);
00494 COND_DESTROY(agent->agent_status_cond);
00495 free(agent->agent_status_cond);
00496
00497 MUTEX_UNLOCK(agent->lock);
00498 MUTEX_DESTROY(agent->lock);
00499 free(agent->lock);
00500 agent_datastate_Destroy(agent->datastate);
00501 free(agent->run_lock);
00502 ListWRLock(agent->mailbox);
00503 ListClearCB(agent->mailbox, (ListElemDestroyFunc_t)fipa_acl_message_Destroy);
00504 ListWRUnlock(agent->mailbox);
00505 ListTerminate(agent->mailbox);
00506
00507 free(agent);
00508 agent = NULL;
00509 return MC_SUCCESS;
00510 }
00511
00512 extern void
00513 agent_RunChScript(agent_p agent, mc_platform_p mc_platform)
00514 {
00515 #ifndef _WIN32
00516 pthread_attr_t attr;
00517 pthread_attr_init(&attr);
00518 if(mc_platform->stack_size[MC_THREAD_AGENT] != -1) {
00519 pthread_attr_setstacksize
00520 (
00521 &attr,
00522 mc_platform->stack_size[MC_THREAD_AGENT]
00523 );
00524 }
00525 pthread_attr_setdetachstate
00526 (
00527 &attr,
00528 PTHREAD_CREATE_DETACHED
00529 );
00530 #else
00531 int stack_size;
00532 if (mc_platform->stack_size[MC_THREAD_AGENT] < 1) {
00533 stack_size = mc_platform->stack_size[MC_THREAD_AGENT]+1;
00534 } else {
00535 stack_size = mc_platform->stack_size[MC_THREAD_AGENT];
00536 }
00537 #endif
00538 MUTEX_LOCK(agent->agent_status_lock);
00539 agent->agent_status = MC_AGENT_ACTIVE;
00540 COND_BROADCAST(agent->agent_status_cond);
00541 MUTEX_UNLOCK(agent->agent_status_lock);
00542 agent->mc_platform = mc_platform;
00543
00544 THREAD_CREATE(&agent->agent_thread,
00545 agent_RunChScriptThread,
00546 agent );
00547
00548 return;
00549 }
00550
00551
00552
00553 void *
00554 agent_ChScriptInitVar(ChInterp_t* interp)
00555 {
00556 char *tmp_buf;
00557
00558
00559 tmp_buf = (char*)malloc(sizeof(char) * 200);
00560 tmp_buf[0] = '\0';
00561 sprintf(tmp_buf, "int mc_agent_id = -1;");
00562 Ch_DeclareVar(
00563 *interp,
00564 tmp_buf
00565 );
00566
00567 tmp_buf[0] = '\0';
00568
00569 sprintf(tmp_buf, "char* mc_agent_name = NULL;");
00570 Ch_DeclareVar(
00571 *interp,
00572 tmp_buf
00573 );
00574
00575 tmp_buf[0] = '\0';
00576 sprintf(tmp_buf, "void* mc_current_agent = NULL;");
00577 Ch_DeclareVar(
00578 *interp,
00579 tmp_buf
00580 );
00581
00582 tmp_buf[0] = '\0';
00583
00584 sprintf(tmp_buf, "char* mc_host_name = NULL;");
00585 Ch_DeclareVar(
00586 *interp,
00587 tmp_buf
00588 );
00589
00590 tmp_buf[0] = '\0';
00591 sprintf(tmp_buf, "int mc_host_port = -1;\n");
00592 Ch_DeclareVar(
00593 *interp,
00594 tmp_buf
00595 );
00596
00597 tmp_buf[0] = '\0';
00598 sprintf(tmp_buf, "int mc_task_progress = -1;\n");
00599 Ch_DeclareVar(
00600 *interp,
00601 tmp_buf
00602 );
00603
00604 tmp_buf[0] = '\0';
00605 sprintf(tmp_buf, "int mc_num_tasks = -1;\n");
00606 Ch_DeclareVar(
00607 *interp,
00608 tmp_buf
00609 );
00610
00611
00612 tmp_buf[0] = '\0';
00613 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 };" );
00614 Ch_DeclareVar(
00615 *interp,
00616 tmp_buf
00617 );
00618
00619 Ch_DeclareVar(
00620 *interp,
00621 "char* mc_agent_address;"
00622 );
00623
00624
00625 tmp_buf[0] = '\0';
00626 sprintf(tmp_buf, "enum MC_SteerCommand_e {MC_RUN = 0, MC_SUSPEND, MC_RESTART, MC_STOP};" );
00627 Ch_DeclareVar(
00628 *interp,
00629 tmp_buf
00630 );
00631
00632 tmp_buf[0] = '\0';
00633 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};");
00634 Ch_DeclareVar(
00635 *interp,
00636 tmp_buf
00637 );
00638
00639 free(tmp_buf);
00640
00641 Ch_DeclareVar(
00642 *interp,
00643 "void* MCAgent_t;"
00644 );
00645 Ch_DeclareTypedef(
00646 *interp,
00647 "MCAgent_t"
00648 );
00649
00650
00651 Ch_DeclareFunc(
00652 *interp,
00653 "int mc_AclDestroy(void* acl_message);",
00654 (ChFuncdl_t)MC_AclDestroy_chdl
00655 );
00656 Ch_DeclareFunc(
00657 *interp,
00658 "void* mc_AclNew(void);",
00659 (ChFuncdl_t)MC_AclNew_chdl
00660 );
00661 Ch_DeclareFunc(
00662 *interp,
00663 "int mc_AclPost(void* agent, void* acl_message);",
00664 (ChFuncdl_t)MC_AclPost_chdl
00665 );
00666 Ch_DeclareFunc(
00667 *interp,
00668 "void* mc_AclRetrieve(void* agent);",
00669 (ChFuncdl_t)MC_AclRetrieve_chdl
00670 );
00671 Ch_DeclareFunc(
00672 *interp,
00673 "void* mc_AclReply(void* acl_message);",
00674 (ChFuncdl_t)MC_AclReply_chdl
00675 );
00676 Ch_DeclareFunc(
00677 *interp,
00678 "int mc_AclSend(void* acl_message);",
00679 (ChFuncdl_t)MC_AclSend_chdl
00680 );
00681 Ch_DeclareFunc(
00682 *interp,
00683 "void* mc_AclWaitRetrieve(void* agent);",
00684 (ChFuncdl_t)MC_AclWaitRetrieve_chdl
00685 );
00686
00687 Ch_DeclareFunc(
00688 *interp,
00689 "int mc_AclGetProtocol(void* acl_message);",
00690 (ChFuncdl_t)MC_AclGetProtocol_chdl
00691 );
00692 Ch_DeclareFunc(
00693 *interp,
00694 "char* mc_AclGetConversationID(void* acl_message);",
00695 (ChFuncdl_t)MC_AclGetConversationID_chdl
00696 );
00697 Ch_DeclareFunc(
00698 *interp,
00699 "int mc_AclGetPerformative(void* acl_message);",
00700 (ChFuncdl_t)MC_AclGetPerformative_chdl
00701 );
00702 Ch_DeclareFunc(
00703 *interp,
00704 "int mc_AclGetSender(void* acl_message, char** name, char** address);",
00705 (ChFuncdl_t)MC_AclGetSender_chdl
00706 );
00707 Ch_DeclareFunc(
00708 *interp,
00709 "char* mc_AclGetContent(void* acl_message);",
00710 (ChFuncdl_t)MC_AclGetContent_chdl
00711 );
00712
00713 Ch_DeclareFunc(
00714 *interp,
00715 "int mc_AclSetProtocol(void* acl_message, int protocol);",
00716 (ChFuncdl_t)MC_AclSetProtocol_chdl
00717 );
00718 Ch_DeclareFunc(
00719 *interp,
00720 "int mc_AclSetConversationID(void* acl_message, char* id);",
00721 (ChFuncdl_t)MC_AclSetConversationID_chdl
00722 );
00723 Ch_DeclareFunc(
00724 *interp,
00725 "int mc_AclSetPerformative(void* acl_message, int performative);",
00726 (ChFuncdl_t)MC_AclSetPerformative_chdl
00727 );
00728 Ch_DeclareFunc(
00729 *interp,
00730 "int mc_AclSetSender(void* acl_message, char* name, char* address);",
00731 (ChFuncdl_t)MC_AclSetSender_chdl
00732 );
00733 Ch_DeclareFunc(
00734 *interp,
00735 "int mc_AclAddReceiver(void* acl_message, char* name, char* address);",
00736 (ChFuncdl_t)MC_AclAddReceiver_chdl
00737 );
00738 Ch_DeclareFunc(
00739 *interp,
00740 "int mc_AclAddReplyTo(void* acl_message, char* name, char* address);",
00741 (ChFuncdl_t)MC_AclAddReplyTo_chdl
00742 );
00743 Ch_DeclareFunc(
00744 *interp,
00745 "int mc_AclSetContent(void* acl_message, char* content);",
00746 (ChFuncdl_t)MC_AclSetContent_chdl
00747 );
00748
00749 Ch_DeclareFunc(
00750 *interp,
00751 "int mc_AddAgent(void* agent);",
00752 (ChFuncdl_t)MC_AddAgent_chdl
00753 );
00754 Ch_DeclareFunc(
00755 *interp,
00756 "int mc_AgentAddTask(void* agent, const char* code, const char* return_var_name, const char* server, int persistent);",
00757 (ChFuncdl_t)MC_AgentAddTask_chdl
00758 );
00759 Ch_DeclareFunc(
00760 *interp,
00761 "int mc_AgentAttachFile(void* agent, const char* name, const char* filepath);",
00762 (ChFuncdl_t)MC_AgentAttachFile_chdl
00763 );
00764 Ch_DeclareFunc(
00765 *interp,
00766 "int mc_AgentListFiles(void* agent, int task_num, char*** names, int* num_files);",
00767 (ChFuncdl_t)MC_AgentListFiles_chdl
00768 );
00769 Ch_DeclareFunc(
00770 *interp,
00771 "int mc_AgentRetrieveFile(void* agent, int task_num, const char* name, const char* save_path);",
00772 (ChFuncdl_t)MC_AgentRetrieveFile_chdl
00773 );
00774 Ch_DeclareFunc(
00775 *interp,
00776 "const void* mc_AgentVariableRetrieve(void* agent, const char* var_name, int task_num);",
00777 (ChFuncdl_t)MC_AgentVariableRetrieve_chdl
00778 );
00779 Ch_DeclareFunc(
00780 *interp,
00781 "int mc_AgentVariableSave(void* agent, const char* var_name);",
00782 (ChFuncdl_t)MC_AgentVariableSave_chdl
00783 );
00784 Ch_DeclareFunc(
00785 *interp,
00786 "int mc_Barrier(int id);",
00787 (ChFuncdl_t)MC_Barrier_chdl
00788 );
00789 Ch_DeclareFunc(
00790 *interp,
00791 "int mc_BarrierDelete(int id);",
00792 (ChFuncdl_t)MC_BarrierDelete_chdl
00793 );
00794 Ch_DeclareFunc(
00795 *interp,
00796 "int mc_BarrierInit(int id, int num_procs);",
00797 (ChFuncdl_t)MC_BarrierInit_chdl
00798 );
00799 Ch_DeclareFunc(
00800 *interp,
00801 "int mc_CallAgentFunc(char* agentName, const char* funcName, void* returnVal, ...);",
00802 (ChFuncdl_t)MC_CallAgentFunc_chdl
00803 );
00804 Ch_DeclareFunc(
00805 *interp,
00806 "MCAgent_t mc_ComposeAgent(const char* name, *home, *owner, *code, *return_var_name, *server, int persistent);",
00807 (ChFuncdl_t)MC_ComposeAgent_chdl
00808 );
00809 Ch_DeclareFunc(
00810 *interp,
00811 "MCAgent_t mc_ComposeAgentS(const char* name, *home, *owner, *code, *return_var_name, *server, *workgroup_code, int persistent);",
00812 (ChFuncdl_t)MC_ComposeAgentWithWorkgroup_chdl
00813 );
00814 Ch_DeclareFunc(
00815 *interp,
00816 "MCAgent_t mc_ComposeAgentWithWorkgroup(const char* name, *home, *owner, *code, *return_var_name, *server, *workgroup_code, int persistent);",
00817 (ChFuncdl_t)MC_ComposeAgentWithWorkgroup_chdl
00818 );
00819 Ch_DeclareFunc(
00820 *interp,
00821 "MCAgent_t mc_ComposeAgentFromFile(const char* name, *home, *owner, *filename, *return_var_name, *server, int persistent);",
00822 (ChFuncdl_t)MC_ComposeAgentFromFile_chdl
00823 );
00824 Ch_DeclareFunc(
00825 *interp,
00826 "MCAgent_t mc_ComposeAgentFromFileWithWorkgroup(const char* name, *home, *owner, *filename, *return_var_name, *server, *workgroup_code, int persistent);",
00827 (ChFuncdl_t)MC_ComposeAgentFromFileWithWorkgroup_chdl
00828 );
00829 Ch_DeclareFunc(
00830 *interp,
00831 "int mc_CondBroadcast(int id);",
00832 (ChFuncdl_t)MC_CondBroadcast_chdl
00833 );
00834 Ch_DeclareFunc(
00835 *interp,
00836 "int mc_CondSignal(int id);",
00837 (ChFuncdl_t)MC_CondSignal_chdl
00838 );
00839 Ch_DeclareFunc(
00840 *interp,
00841 "int mc_CondReset(int id);",
00842 (ChFuncdl_t)MC_CondReset_chdl
00843 );
00844 Ch_DeclareFunc(
00845 *interp,
00846 "int mc_CondWait(int id);",
00847 (ChFuncdl_t)MC_CondWait_chdl
00848 );
00849 Ch_DeclareFunc(
00850 *interp,
00851 "int mc_DeleteAgent(const char* agentName);",
00852 (ChFuncdl_t)MC_DeleteAgent_chdl
00853 );
00854 Ch_DeclareFunc(
00855 *interp,
00856 "int mc_DeleteAgentWG(MCAgent_t calling_agent, const char* agentName);",
00857 (ChFuncdl_t)MC_DeleteAgentWG_chdl
00858 );
00859 Ch_DeclareFunc(
00860 *interp,
00861 "int mc_DeregisterService(int agentID, char* serviceName);",
00862 (ChFuncdl_t)MC_DeregisterService_chdl
00863 );
00864 Ch_DeclareFunc(
00865 *interp,
00866 "int mc_DestroyServiceSearchResult( char** agentName, char** serviceName, int* agentID, int numResult);",
00867 (ChFuncdl_t)MC_DestroyServiceSearchResult_chdl
00868 );
00869 Ch_DeclareFunc(
00870 *interp,
00871 "int mc_End(void);",
00872 (ChFuncdl_t)MC_End_chdl
00873 );
00874 Ch_DeclareFunc(
00875 *interp,
00876 "void *mc_FindAgentByID(int id);",
00877 (ChFuncdl_t)MC_FindAgentByID_chdl
00878 );
00879
00880 Ch_DeclareFunc(
00881 *interp,
00882 "void *mc_FindAgentByName(const char *name);",
00883 (ChFuncdl_t)MC_FindAgentByName_chdl
00884 );
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 Ch_DeclareFunc(
00895 *interp,
00896 "int MC_GetAgentID(void* agent);",
00897 (ChFuncdl_t)MC_GetAgentStatus_chdl
00898 );
00899 Ch_DeclareFunc(
00900 *interp,
00901 "char* MC_GetAgentName(void* agent);",
00902 (ChFuncdl_t)MC_GetAgentStatus_chdl
00903 );
00904 Ch_DeclareFunc(
00905 *interp,
00906 "int mc_GetAgentStatus(void* agent);",
00907 (ChFuncdl_t)MC_GetAgentStatus_chdl
00908 );
00909 Ch_DeclareFunc(
00910 *interp,
00911 "char *mc_GetAgentXMLString(void* agent);",
00912 (ChFuncdl_t)MC_GetAgentXMLString_chdl
00913 );
00914
00915 #ifndef _WIN32
00916 Ch_DeclareFunc(
00917 *interp,
00918 "int mc_gettimeofday(void* tv);",
00919 (ChFuncdl_t)MC_GetTimeOfDay_chdl
00920 );
00921 #endif
00922
00923 Ch_DeclareFunc(
00924 *interp,
00925 "int mc_HaltAgency(void);",
00926 (ChFuncdl_t)MC_HaltAgency_chdl
00927 );
00928 Ch_DeclareFunc(
00929 *interp,
00930 "int mc_MigrateAgent(void* agent, const char* hostname, int port);",
00931 (ChFuncdl_t)MC_MigrateAgent_chdl
00932 );
00933 Ch_DeclareFunc(
00934 *interp,
00935 "int mc_MutexLock(int id);",
00936 (ChFuncdl_t)MC_MutexLock_chdl
00937 );
00938 Ch_DeclareFunc(
00939 *interp,
00940 "int mc_MutexUnlock(int id);",
00941 (ChFuncdl_t)MC_MutexUnlock_chdl
00942 );
00943 Ch_DeclareFunc(
00944 *interp,
00945 "int mc_PrintAgentCode(void* agent);",
00946 (ChFuncdl_t)MC_PrintAgentCode_chdl
00947 );
00948 Ch_DeclareFunc(
00949 *interp,
00950 "int mc_ResumeAgency(void);",
00951 (ChFuncdl_t)MC_ResumeAgency_chdl
00952 );
00953 Ch_DeclareFunc(
00954 *interp,
00955 "int mc_SearchForService(const char* searchString, char*** agentNames, char*** serviceNames, int** agentIDs, int* numResults);",
00956 (ChFuncdl_t)MC_SearchForService_chdl
00957 );
00958 Ch_DeclareFunc(
00959 *interp,
00960 "int mc_SendSteerCommand(enum MC_SteerCommand_e command);",
00961 (ChFuncdl_t)MC_SendSteerCommand_chdl
00962 );
00963 Ch_DeclareFunc(
00964 *interp,
00965 "int mc_RegisterService(MCAgent_t agent, char **serviceNames, int numServices);",
00966 (ChFuncdl_t)MC_RegisterService_chdl
00967 );
00968 Ch_DeclareFunc(
00969 *interp,
00970 "void *mc_RetrieveAgent(void);",
00971 (ChFuncdl_t)MC_RetrieveAgent_chdl
00972 );
00973 Ch_DeclareFunc(
00974 *interp,
00975 "char *mc_RetrieveAgentCode(void* agent);",
00976 (ChFuncdl_t)MC_RetrieveAgentCode_chdl
00977 );
00978 Ch_DeclareFunc(
00979 *interp,
00980 "int mc_SaveData(MCAgent_t agent, char* name, int size, void* data);",
00981 (ChFuncdl_t)MC_SaveData_chdl
00982 );
00983 Ch_DeclareFunc(
00984 *interp,
00985 "int mc_SemaphoreWait(int id);",
00986 (ChFuncdl_t)MC_SemaphoreWait_chdl
00987 );
00988 Ch_DeclareFunc(
00989 *interp,
00990 "int mc_SemaphorePost(int id);",
00991 (ChFuncdl_t)MC_SemaphorePost_chdl
00992 );
00993 Ch_DeclareFunc(
00994 *interp,
00995 "int mc_SendAgentMigrationMessage(char *message, char *hostname, int port);",
00996 (ChFuncdl_t)MC_SendAgentMigrationMessage_chdl
00997 );
00998 Ch_DeclareFunc(
00999 *interp,
01000 "int mc_SendAgentMigrationMessageFile(char *filename, char *hostname, int port);",
01001 (ChFuncdl_t)MC_SendAgentMigrationMessageFile_chdl
01002 );
01003 Ch_DeclareFunc(
01004 *interp,
01005 "int mc_SetAgentStatus(void* agent, int status);",
01006 (ChFuncdl_t)MC_SetAgentStatus_chdl
01007 );
01008 Ch_DeclareFunc(
01009 *interp,
01010 "int mc_SetDefaultAgentStatus(int status);",
01011 (ChFuncdl_t)MC_SetDefaultAgentStatus_chdl
01012 );
01013 Ch_DeclareFunc(
01014 *interp,
01015 "int mc_SyncDelete(int id);",
01016 (ChFuncdl_t)MC_SyncDelete_chdl
01017 );
01018 Ch_DeclareFunc(
01019 *interp,
01020 "int mc_SyncInit(int id);",
01021 (ChFuncdl_t)MC_SyncInit_chdl
01022 );
01023 Ch_DeclareFunc(
01024 *interp,
01025 "int mc_TerminateAgent(const char* agentName);",
01026 (ChFuncdl_t)MC_TerminateAgent_chdl
01027 );
01028 Ch_DeclareFunc(
01029 *interp,
01030 "int mc_TerminateAgentWG(void* callingAgent, const char* agentName);",
01031 (ChFuncdl_t)MC_TerminateAgentWG_chdl
01032 );
01033 Ch_DeclareFunc(
01034 *interp,
01035 "int mc_GetAgentID(void* agent);",
01036 (ChFuncdl_t)MC_GetAgentID_chdl
01037 );
01038 Ch_DeclareFunc(
01039 *interp,
01040 "char *mc_GetAgentName(void* agent);",
01041 (ChFuncdl_t)MC_GetAgentName_chdl
01042 );
01043
01044 return NULL;
01045 }
01046
01047 #ifndef _WIN32
01048 void*
01049 agent_RunChScriptThread(void * ChAgent)
01050 #else
01051 DWORD WINAPI
01052 agent_RunChScriptThread(void* ChAgent)
01053 #endif
01054 {
01055 #ifndef _WIN32
01056 int fd;
01057 #endif
01058 MCAgent_t agent;
01059 mc_platform_p mc_platform;
01060 int i,n;
01061 FILE *TEMP_FILE;
01062 char *temp_store_file;
01063 char *ChShellArg[2];
01064 void *result;
01065 int progress;
01066 int callbackErrCode;
01067 int persistent = 0;
01068
01069
01070 agent = (MCAgent_t)ChAgent;
01071 progress = agent->datastate->task_progress;
01072 mc_platform = agent->mc_platform;
01073
01074 setbuf(stdout, NULL);
01075 setbuf(stderr, NULL);
01076
01077 if(ChAgent == NULL)
01078 {
01079 printf("ERROR, AGENT NULL \n");
01080 #ifndef _WIN32
01081 return NULL;
01082 #else
01083 return 0;
01084 #endif
01085 }
01086
01087
01088 agent->agent_interp = (ChInterp_t *)interpreter_queue_CreateRetrieve(mc_platform->interpreter_queue,
01089 agent->mc_platform->interp_options );
01090 if(agent->agent_interp == NULL) {
01091
01092 WARN("Could not initialize another Ch interperter. Please make more copies of the chmt*.dl file.\n");
01093 return NULL;
01094 }
01095
01096
01097
01098 Ch_SetVar(*agent->agent_interp, "mc_agent_id",
01099 CH_INTTYPE, (int)agent->id);
01100
01101 Ch_SetVar(*agent->agent_interp, "mc_agent_name",
01102 CH_CHARPTRTYPE, agent->name);
01103
01104 Ch_SetVar(*agent->agent_interp, "mc_current_agent",
01105 CH_VOIDPTRTYPE, (void*)((size_t)agent));
01106
01107 Ch_SetVar(*agent->agent_interp, "mc_host_name",
01108 CH_CHARPTRTYPE, agent->mc_platform->hostname);
01109
01110 Ch_SetVar(*agent->agent_interp, "mc_host_port",
01111 CH_INTTYPE, (int)agent->mc_platform->port);
01112
01113 Ch_SetVar(*agent->agent_interp, "mc_task_progress",
01114 CH_INTTYPE, (int)agent->datastate->task_progress);
01115
01116 Ch_SetVar(*agent->agent_interp, "mc_num_tasks",
01117 CH_INTTYPE, (int)agent->datastate->number_of_tasks);
01118
01119 Ch_SetVar(*agent->agent_interp, "mc_agent_address",
01120 CH_CHARPTRTYPE, agent->agent_address);
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 if(strlen(agent->datastate->agent_code) < 5)
01132 {
01133 MUTEX_LOCK(agent->run_lock);
01134 if(Ch_AppendRunScript(
01135 *((MCAgent_t)ChAgent)->agent_interp,
01136 ((MCAgent_t)ChAgent)->datastate->agent_code))
01137 {
01138
01139 printf("CH Failure \n");
01140 printf("***************************************************\nCode was:\n%s\n\n", agent->datastate->agent_code);
01141
01142 }
01143 if(Ch_CallFuncByName(*((MCAgent_t)ChAgent)->agent_interp, "main", NULL))
01144 {
01145 printf("CH2 failure \n");
01146 exit(EXIT_FAILURE);
01147 }
01148 MUTEX_UNLOCK(agent->run_lock);
01149 }
01150 else
01151 {
01152
01153
01154 if(mc_platform->agency->agentInitCallback) {
01155 callbackErrCode = (mc_platform->agency->agentInitCallback)(
01156 *agent->agent_interp,
01157 (struct agent_s*)agent,
01158 mc_platform->agency->agentInitUserData );
01159 if(callbackErrCode) {
01160
01161 ((MCAgent_t) ChAgent)->agent_status = MC_AGENT_NEUTRAL;
01162 #ifndef _WIN32
01163 pthread_exit(ChAgent);
01164 #else
01165 return 0;
01166 #endif
01167 }
01168 }
01169
01170 #ifndef _WIN32
01171
01172 temp_store_file = (char *)malloc(sizeof(char)*30);
01173
01174 strcpy(temp_store_file, "agentchscriptXXXXXX");
01175 fd = mkstemp(temp_store_file);
01176 if (fd == -1) {
01177 fprintf(stderr, "Could not create temporary file:%s. %s:%d\n",
01178 temp_store_file,
01179 __FILE__,
01180 __LINE__ );
01181 exit(EXIT_FAILURE);
01182 }
01183 close(fd);
01184 #else
01185 temp_store_file = _tempnam(".", "agentchscript");
01186 #endif
01187 TEMP_FILE = fopen(temp_store_file, "w");
01188
01189
01190 n = fwrite(
01191 (void *)agent->datastate->agent_code,
01192 sizeof(char),
01193 strlen(agent->datastate->agent_code),
01194 TEMP_FILE);
01195
01196 fclose(TEMP_FILE);
01197
01198
01199 ChShellArg[0] = temp_store_file;
01200 ChShellArg[1] = NULL;
01201 MUTEX_LOCK(agent->run_lock);
01202 if(Ch_RunScript(*agent->agent_interp, ChShellArg) < 0) {
01203 fprintf(stderr, "Ch_RunScript error. %s:%d\n", __FILE__, __LINE__);
01204 } else {
01205
01206 fflush(stdout);
01207 }
01208
01209
01210
01211
01212
01213
01214
01215
01216 remove(temp_store_file);
01217 #ifndef _WIN32
01218 free(temp_store_file);
01219 #endif
01220 MUTEX_UNLOCK(agent->run_lock);
01221 }
01222
01223
01224 if(
01225 agent->datastate->tasks[progress]->var_name != NULL &&
01226 strcmp(agent->datastate->tasks[progress]->var_name, "no-return")
01227 )
01228 {
01229 result = interpreter_variable_data_InitializeFromAgent(agent);
01230
01231 interpreter_variable_data_Destroy(
01232 agent->datastate->tasks[progress]->agent_return_data
01233 );
01234
01235 agent->datastate->tasks[progress]->agent_return_data =
01236 (interpreter_variable_data_t*)result;
01237 } else {
01238 interpreter_variable_data_Destroy(
01239 agent->datastate->tasks[progress]->agent_return_data );
01240 agent->datastate->tasks[progress]->agent_return_data = NULL;
01241 }
01242
01243
01244
01245
01246 ListClearCB(
01247 agent->datastate->tasks[progress]->agent_variable_list,
01248 (ListElemDestroyFunc_t) interpreter_variable_data_Destroy);
01249
01250 for(i = 0; i < agent->datastate->tasks[progress]->num_saved_variables; i++) {
01251
01252
01253
01254
01255 ListWRLock(agent->datastate->tasks[progress]->agent_variable_list);
01256 ListAdd(
01257 agent->datastate->tasks[progress]->agent_variable_list,
01258 interpreter_variable_data_Initialize(
01259 agent,
01260 agent->datastate->tasks[progress]->saved_variables[i] )
01261 );
01262 ListWRUnlock(agent->datastate->tasks[progress]->agent_variable_list);
01263 }
01264
01265
01266 agent->datastate->task_progress += agent->datastate->progress_modifier;
01267
01268 if (agent->datastate->persistent ||
01269 agent->datastate->tasks[progress]->persistent ) {
01270 persistent = 1;
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 ((MCAgent_t) ChAgent)->agent_status = MC_AGENT_NEUTRAL;
01283 } else {
01284 if ((((MCAgent_t)ChAgent)->agent_interp) != NULL) {
01285
01286 Ch_Reset(*agent->agent_interp);
01287 ListWRLock(mc_platform->interpreter_queue);
01288 ListAdd(mc_platform->interpreter_queue, agent->agent_interp);
01289 ListWRUnlock(mc_platform->interpreter_queue);
01290 }
01291
01292
01293 if (
01294 (agent->datastate->task_progress ==
01295 (agent->datastate->number_of_tasks-1))
01296 )
01297 {
01298
01299 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_FINISHED;
01300
01301
01302 for(i = 0;
01303 i < agent->datastate->number_of_tasks;
01304 i++)
01305 {
01306 if (agent->datastate->tasks[i]->agent_return_data != NULL) {
01307 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_MESSGSEND;
01308 }
01309 }
01310 }
01311 else {
01312 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_MESSGSEND;
01313 }
01314 }
01315
01316
01317 agent->datastate->task_progress++;
01318
01319 if (
01320 (agent->datastate->task_progress >= agent->datastate->number_of_tasks)
01321 )
01322 {
01323 agent->agent_type = MC_RETURN_AGENT;
01324 }
01325
01326 SIGNAL(
01327 mc_platform->MC_signal_cond,
01328 mc_platform->MC_signal_lock,
01329 mc_platform->MC_signal = MC_EXEC_AGENT;
01330 );
01331
01332 MUTEX_LOCK( mc_platform->MC_signal_lock);
01333 MUTEX_UNLOCK( mc_platform->MC_signal_lock );
01334 MUTEX_LOCK(mc_platform->ams->runflag_lock);
01335 mc_platform->ams->run = 1;
01336 COND_SIGNAL(mc_platform->ams->runflag_cond);
01337 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
01338
01339 if(persistent)
01340 {
01341
01342
01343 MUTEX_LOCK(agent->agent_status_lock);
01344 while(agent->agent_status == MC_AGENT_NEUTRAL) {
01345 COND_WAIT(agent->agent_status_cond, agent->agent_status_lock);
01346 }
01347 MUTEX_UNLOCK(agent->agent_status_lock);
01348 }
01349 #ifndef _WIN32
01350 pthread_exit(ChAgent);
01351 #else
01352 return 0;
01353 #endif
01354 }
01355
01356 int agent_Print(agent_t* agent) {
01357 MUTEX_LOCK(agent->agent_status_lock);
01358 printf("Agent id: %lu, Connect id: %lu, status: %u\n",
01359 agent->id,
01360 agent->connect_id,
01361 agent->agent_status);
01362 MUTEX_UNLOCK(agent->agent_status_lock);
01363 return 0;
01364 }
01365
01366 int agent_CmpName(const void* key, void* element)
01367 {
01368 const char* name = (const char*)key;
01369 agent_t* agent = (agent_t*)element;
01370 int ret;
01371 MUTEX_LOCK(agent->lock);
01372 ret = strcmp(name, agent->name);
01373 MUTEX_UNLOCK(agent->lock);
01374 return ret;
01375 }
01376
01377 int agent_CmpID(int* id, agent_t* agent)
01378 {
01379 int ret;
01380 MUTEX_LOCK(agent->lock);
01381 ret = *id - agent->id;
01382 MUTEX_UNLOCK(agent->lock);
01383 return ret;
01384 }
01385