int start_chassis_cmd(struct katcp_dispatch *d, int argc) { char *match; struct tbs_raw *tr; tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "unable to get raw state"); return KATCP_RESULT_FAIL; } if(tr->r_chassis){ log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "chassis logic already registered"); return KATCP_RESULT_FAIL; } if(argc <= 1){ match = TBS_ROACH_CHASSIS; } else { match = arg_string_katcp(d, 1); if(match == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to acquire valid match"); return KATCP_RESULT_FAIL; } } tr->r_chassis = chassis_init_tbs(d, match); if(tr->r_chassis == NULL){ return KATCP_RESULT_FAIL; } return KATCP_RESULT_OK; }
struct kcs_sm_op *spawn_setup_statemachine_kcs(struct katcp_dispatch *d, struct kcs_sm_state *s) { struct katcp_tobject *o; char *node, *str[2]; node = arg_string_katcp(d, 4); if (node == NULL) return NULL; str[0] = node; str[1] = NULL; o = create_named_tobject_katcp(d, parse_string_type_katcp(d, str), KATCP_TYPE_STRING, 1); if (o == NULL) return NULL; return create_sm_op_kcs(&spawn_statemachine_kcs, o); }
int upload_cmd(struct katcp_dispatch *d, int argc) { struct katcp_dispatch *dl; struct katcp_job *j; struct katcp_url *url; struct tbs_port_data *pd; char *rtn; dl = template_shared_katcp(d); pd = create_port_data_tbs(); if (pd == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: couldn't create port data", __func__); return KATCP_RESULT_FAIL; } #ifdef DEBUG fprintf(stderr, "%s: with %d args\n", __func__, argc); #endif switch (argc){ case 1: pd->t_port = 7146; case 2: rtn = arg_string_katcp(d, 1); if (rtn != NULL) pd->t_port = atoi(rtn); url = create_exec_kurl_katcp("upload"); if (url == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: could not create kurl", __func__); destroy_port_data_tbs(pd); return KATCP_RESULT_FAIL; } j = find_job_katcp(dl, url->u_str); if (j){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: found job for %s", __func__, url->u_str); destroy_kurl_katcp(url); destroy_port_data_tbs(pd); return KATCP_RESULT_FAIL; } j = run_child_process_tbs(dl, url, &upload_tbs, pd, NULL); if (j == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: run child process returned null for %s", __func__ , url->u_str); destroy_kurl_katcp(url); destroy_port_data_tbs(pd); return KATCP_RESULT_FAIL; } if (match_inform_job_katcp(dl, j, UPLOADCOMPLETE, &upload_complete_tbs, pd) < 0){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%s: match inform for job %s failed", __func__, url->u_str); zap_job_katcp(dl,j); destroy_port_data_tbs(pd); return KATCP_RESULT_FAIL; } break; } extra_response_katcp(d, KATCP_RESULT_OK, "%d", pd->t_port); return KATCP_RESULT_OWN; }
int led_chassis_cmd(struct katcp_dispatch *d, int argc) { struct tbs_raw *tr; int code, value; char *name, *parm; if(argc <= 1){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "insufficient parameters"); return KATCP_RESULT_FAIL; } tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "unable to get raw state"); return KATCP_RESULT_FAIL; } if(tr->r_chassis == NULL){ log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "no chassis logic registered"); return KATCP_RESULT_FAIL; } name = arg_string_katcp(d, 1); if(name == NULL){ log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "unable to acquire led name"); return KATCP_RESULT_FAIL; } /* this should be an array lookup, but it is only two leds */ if(!strcmp(name, "red")){ code = LED_SUSPEND; } else if(!strcmp(name, "green")){ code = LED_MISC; } else { log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "unsupported led colour %s", name); return KATCP_RESULT_FAIL; } value = 0; parm = arg_string_katcp(d, 2); if(parm){ if(strcmp(parm, "off") && strcmp(parm, "false") && strcmp(parm, "0") ){ value = 1; } } log_message_katcp(d, KATCP_LEVEL_TRACE, NULL, "%s led code %d", value ? "setting" : "clearing", code); if(write_event_tbs(d, tr->r_chassis, EV_LED, code, value) < 0){ return KATCP_RESULT_FAIL; } if(write_event_tbs(d, tr->r_chassis, EV_SYN, 0, 0) < 0){ return KATCP_RESULT_FAIL; } return KATCP_RESULT_OK; }
struct kcs_sm_op *pushstack_setup_statemachine_kcs(struct katcp_dispatch *d, struct kcs_sm_state *s) { #define ARG_BASE 5 struct katcp_type *t; struct katcp_tobject *o; struct kcs_sm_op *op; char **data, *type; void *ptemp, *stemp; int num, i; stemp = NULL; type = arg_string_katcp(d, 4); if (type == NULL || s == NULL) return NULL; t = find_name_type_katcp(d, type); if (t == NULL){ log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "invalid type: %s\n", type); return NULL; } num = arg_count_katcp(d) - ARG_BASE; data = malloc(sizeof(char *) * (num + 1)); if (data == NULL) return NULL; for (i=0; i<num; i++){ data[i] = arg_string_katcp(d, ARG_BASE + i); #ifdef DEBUG fprintf(stderr, "statemachine: pushsetup data[%d of %d]: %s\n", i+1, num, data[i]); #endif } data[num] = NULL; #ifdef DEBUG fprintf(stderr, "statemachine: call type parse function\n"); #endif ptemp = (*t->t_parse)(d, data); if (data[0] != NULL) stemp = search_type_katcp(d, t, data[0], ptemp); free(data); if (ptemp == NULL){ #ifdef DEBUG fprintf(stderr, "statemachine: type parse fn failed\n"); #endif //return NULL; } if (stemp == NULL){ #ifdef DEBUG fprintf(stderr, "statemachine: type search fn failed\n"); #endif (*t->t_free)(ptemp); return NULL; } o = create_tobject_katcp(stemp, t, 0); if (o == NULL){ (*t->t_free)(stemp); #ifdef DEBUG fprintf(stderr, "statemachine: pushsetup could not create stack obj\n"); #endif return NULL; } op = create_sm_op_kcs(&pushstack_statemachine_kcs, o); if (op == NULL){ (*t->t_free)(stemp); destroy_tobject_katcp(o); return NULL; } #ifdef DEBUG fprintf(stderr, "statemachine: pushsetup created op (%p)\n", op); #endif return op; #undef ARG_BASE }
int test_walsh_cmd(struct katcp_dispatch *d, int argc){ int iter = 0; char *regname; uint32_t value; double sec, msec, period; long long tv_sec, tv_nsec; struct tbs_raw *tr; struct tbs_entry *te; struct timespec start, next, last; /* Grab the mode pointer */ tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to acquire raw mode state"); return KATCP_RESULT_FAIL; } /* Make sure we're programmed */ if(tr->r_fpga != TBS_FPGA_MAPPED){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "fpga not programmed"); return KATCP_RESULT_FAIL; } /* Grab the first argument, name of reg to twiddle */ regname = arg_string_katcp(d, 1); if (regname == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to parse first command line argument"); return KATCP_RESULT_FAIL; } /* Grab the second argument, period in microseconds */ period = (double)arg_unsigned_long_katcp(d, 2) * 1e-3; if (period == 0.0){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to parse second command line argument"); return KATCP_RESULT_FAIL; } log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "period=%.6f ms", period); /* Get the register pointer */ te = find_data_avltree(tr->r_registers, regname); if(te == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "register %s not defined", regname); return KATCP_RESULT_FAIL; } /* Get current value of WALSH_ARM_REG */ value = *((uint32_t *)(tr->r_map + te->e_pos_base)); log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "arm ctrl value = %d", (int)value); /* Loop for a minute */ clock_gettime(CLOCK_REALTIME, &start); start.tv_sec++; start.tv_nsec = 0; while (iter < (int)(60000.0/period)) { iter++; msec = iter * period; sec = msec * 1e-3; tv_sec = (long long)sec; tv_nsec = ((long long)(msec * 1e6) % 1000000000); next.tv_sec = start.tv_sec + tv_sec; next.tv_nsec = start.tv_nsec + tv_nsec; last = wait_for(next); //log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "iter==%lld.%09lld", tv_sec, tv_nsec); /* Twiddle the LSB value */ *((uint32_t *)(tr->r_map + te->e_pos_base)) = value | (iter%2); msync(tr->r_map, tr->r_map_size, MS_SYNC); } log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "start=%d.%09d", start.tv_sec, start.tv_nsec); log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "stop==%d.%09d", last.tv_sec, last.tv_nsec); return KATCP_RESULT_OK; }
int load_plugin_cmd(struct katcp_dispatch *d, int argc) { int i; int result; int n_cmds; char *name; char *error; void *module, *i_module; char *plugin_name, *i_plugin_name; char *plugin_vers, *i_plugin_vers; struct PLUGIN *plugin_info; struct PLUGIN *i_plugin_info; struct PLUGIN_CMD *plugin_cmds; int (* plugin_init)(struct katcp_dispatch *d, int argc); /* Get the filename of the plugin to load */ name = arg_string_katcp(d, 1); if(name == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "internal failure while acquiring parameters"); return KATCP_RESULT_FAIL; } /* Load dynamic library */ module = dlopen(name, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND); if (!module) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "could not open shared object: %s", dlerror()); return KATCP_RESULT_FAIL; } /* Get plugin info */ plugin_info = dlsym(module, "KATCP_PLUGIN"); error = dlerror(); if (error) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "could not find symbol"); dlclose(module); /* make sure to close on failure */ return KATCP_RESULT_FAIL; } /* Get the plugin name */ plugin_name = plugin_info->name; if (plugin_name == NULL) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "plugin name not set"); dlclose(module); /* make sure to close on failure */ return KATCP_RESULT_FAIL; } /* Get the plugin version */ plugin_vers = plugin_info->version; if (plugin_vers == NULL) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "plugin version not set"); dlclose(module); /* make sure to close on failure */ return KATCP_RESULT_FAIL; } /* Check if we've already loaded this plugin */ for (i=0; i<N_LOADED_PLUGINS; i++) { i_module = LOADED_PLUGINS[i]; /* Get plugin info (no error checking needed)*/ i_plugin_info = dlsym(i_module, "KATCP_PLUGIN"); i_plugin_name = i_plugin_info->name; i_plugin_vers = i_plugin_info->version; if (strcmp(plugin_name, i_plugin_name) == 0) { log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "%s(%s) already loaded!", i_plugin_name, i_plugin_vers); dlclose(module); /* make sure to close on failure */ return KATCP_RESULT_FAIL; } } /* Get the init if available */ plugin_init = plugin_info->init; if (plugin_init == NULL) { log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "no plugin init function found"); } else { /* Call init before loading commands */ if (plugin_init(d, argc) != 0) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem while initializing"); dlclose(module); /* make sure to close on failure */ return KATCP_RESULT_FAIL; } } /* Get total commands available */ n_cmds = plugin_info->n_cmds; if (n_cmds == 0) { log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "plugin says no commands available"); } /* Get array of functions */ plugin_cmds = plugin_info->cmd_array; if (plugin_cmds == NULL) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "no commands found"); } /* Load commands into tcpborphserver */ for (i=0; i<n_cmds; i++) { struct PLUGIN_CMD cmd = plugin_cmds[i]; log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "found command: %s", cmd.name); result = register_flag_mode_katcp(d, cmd.name, cmd.desc, cmd.cmd, 0, TBS_MODE_RAW); if (result) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "error loading: ", cmd.name); dlclose(module); /* make sure to close on failure */ return KATCP_RESULT_FAIL; } } /* Expand the plugins list */ void **temp = realloc(LOADED_PLUGINS, (N_LOADED_PLUGINS+1) * sizeof(void *)); if (temp == NULL) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem reallocing plugins list"); dlclose(module); /* make sure to close on failure */ return KATCP_RESULT_FAIL; } /* Add our module to new list */ LOADED_PLUGINS = temp; LOADED_PLUGINS[N_LOADED_PLUGINS] = module; /* And finally increment the plugins counter */ N_LOADED_PLUGINS++; return extra_response_katcp(d, KATCP_RESULT_OK, "%d commands loaded successfully", n_cmds); }
int unload_plugin_cmd(struct katcp_dispatch *d, int argc) { int i, j, k; int past = 0; int found = 0; int result; int n_cmds; char *name; void *module; char *plugin_name; struct PLUGIN *plugin_info; struct PLUGIN_CMD *plugin_cmds; int (* plugin_uninit)(struct katcp_dispatch *d, int argc); /* Check if we haven't loaded any plugins */ if (LOADED_PLUGINS == NULL) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "no plugins have been loaded"); return KATCP_RESULT_FAIL; } /* Get the name of the plugin to unload */ name = arg_string_katcp(d, 1); if(name == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "internal failure while acquiring parameters"); return KATCP_RESULT_FAIL; } for (i=0; i<N_LOADED_PLUGINS; i++) { module = LOADED_PLUGINS[i]; /* Get plugin info (no error checking needed)*/ plugin_info = dlsym(module, "KATCP_PLUGIN"); plugin_name = plugin_info->name; if (strcmp(name, plugin_name) == 0) { /* Print info on each loaded module */ log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "found plugin %s", plugin_name); found = 1; break; } } /* Get out if plugin hasn't been loaded */ if (!found) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "plugin not found. cannot unload"); return KATCP_RESULT_FAIL; } /* Get the uninit if available */ plugin_uninit = plugin_info->uninit; if (plugin_uninit == NULL) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "no plugin uninit function found"); } else { /* Call uninit before closing */ if (plugin_uninit(d, argc) != 0) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem while uninitializing"); return KATCP_RESULT_FAIL; } } /* Now deregister the katcp commands */ n_cmds = plugin_info->n_cmds; plugin_cmds = plugin_info->cmd_array; for (j=0; j<n_cmds; j++) { struct PLUGIN_CMD cmd = plugin_cmds[j]; result = deregister_command_katcp(d, cmd.name); if (result) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem deregistering: ", cmd.name); return KATCP_RESULT_FAIL; } } /* Now close the dynamic module */ dlclose(module); /* Allocate new plugins list */ void **temp = malloc((N_LOADED_PLUGINS-1) * sizeof(void *)); if (temp == NULL) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "problem allocing plugins list"); return KATCP_RESULT_FAIL; } /* Remove module from plugins list */ for (k=0; k<N_LOADED_PLUGINS; k++) { if (k == i) { past = 1; } else { temp[k-past] = LOADED_PLUGINS[k]; } } free(LOADED_PLUGINS); LOADED_PLUGINS = temp; /* And finally decrement the plugins counter */ N_LOADED_PLUGINS--; return extra_response_katcp(d, KATCP_RESULT_OK, "%s plugin unloaded", name); }