MIDAS
Loading...
Searching...
No Matches
mjsonrpc.cxx File Reference
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <map>
#include "mjson.h"
#include "midas.h"
#include "msystem.h"
#include "mstrlcpy.h"
#include "mjsonrpc.h"
#include <mutex>
#include "history.h"
Include dependency graph for mjsonrpc.cxx:

Go to the source code of this file.

Classes

class  JsonHistoryBuffer
 
class  BinaryHistoryBuffer
 
struct  EventStashEntry
 
struct  MethodsTableEntry
 
struct  NestedLine
 
class  NestedOutput
 

Typedefs

typedef std::map< std::string, MidasHistoryInterface * > MhiMap
 
typedef std::map< std::string, MethodsTableEntryMethodsTable
 
typedef MethodsTable::iterator MethodsTableIterator
 

Functions

static double GetTimeSec ()
 
MJsonNode * mjsonrpc_make_error (int code, const char *message, const char *data)
 
MJsonNode * mjsonrpc_make_result (MJsonNode *node)
 
MJsonNode * mjsonrpc_make_result (const char *name, MJsonNode *value, const char *name2, MJsonNode *value2, const char *name3, MJsonNode *value3)
 
MJsonNode * mjsonrpc_make_result (const char *name, MJsonNode *value, const char *name2, MJsonNode *value2, const char *name3, MJsonNode *value3, const char *name4, MJsonNode *value4)
 
const MJsonNode * mjsonrpc_get_param (const MJsonNode *params, const char *name, MJsonNode **error)
 
const MJsonNodeVector * mjsonrpc_get_param_array (const MJsonNode *params, const char *name, MJsonNode **error)
 
static std::string remove (const std::string s, char c)
 
static MJsonNode * xnull (const MJsonNode *params)
 
static MJsonNode * js_cm_exist (const MJsonNode *params)
 
static MJsonNode * js_cm_shutdown (const MJsonNode *params)
 
static MJsonNode * start_program (const MJsonNode *params)
 
static MJsonNode * exec_script (const MJsonNode *params)
 
static int parse_array_index_list (const char *method, const char *path, std::vector< unsigned > *list)
 
static MJsonNode * js_db_get_values (const MJsonNode *params)
 
static MJsonNode * js_db_ls (const MJsonNode *params)
 
static MJsonNode * js_db_copy (const MJsonNode *params)
 
static MJsonNode * js_db_paste (const MJsonNode *params)
 
static MJsonNode * js_db_create (const MJsonNode *params)
 
static MJsonNode * js_db_delete (const MJsonNode *params)
 
static MJsonNode * js_db_resize (const MJsonNode *params)
 
static MJsonNode * js_db_resize_string (const MJsonNode *params)
 
static MJsonNode * js_db_key (const MJsonNode *params)
 
static MJsonNode * js_db_rename (const MJsonNode *params)
 
static MJsonNode * js_db_link (const MJsonNode *params)
 
static MJsonNode * js_db_reorder (const MJsonNode *params)
 
static MJsonNode * js_db_sor (const MJsonNode *params)
 
static MJsonNode * js_db_scl (const MJsonNode *params)
 
static MJsonNode * js_cm_msg_facilities (const MJsonNode *params)
 
static MJsonNode * js_cm_msg1 (const MJsonNode *params)
 
static MJsonNode * js_cm_msg_retrieve (const MJsonNode *params)
 
static MJsonNode * js_al_reset_alarm (const MJsonNode *params)
 
static MJsonNode * js_al_trigger_alarm (const MJsonNode *params)
 
static MJsonNode * js_al_trigger_class (const MJsonNode *params)
 
static MJsonNode * js_hs_get_active_events (const MJsonNode *params)
 
static MidasHistoryInterfaceGetHistory (const char *name)
 
static void js_hs_exit ()
 
static MJsonNode * js_hs_get_channels (const MJsonNode *params)
 
static MJsonNode * js_hs_get_events (const MJsonNode *params)
 
static MJsonNode * js_hs_reopen (const MJsonNode *params)
 
static MJsonNode * js_hs_get_tags (const MJsonNode *params)
 
static MJsonNode * js_hs_get_last_written (const MJsonNode *params)
 
static MJsonNode * js_hs_read (const MJsonNode *params)
 
static MJsonNode * js_hs_read_binned (const MJsonNode *params)
 
static MJsonNode * js_hs_read_arraybuffer (const MJsonNode *params)
 
static MJsonNode * js_hs_read_binned_arraybuffer (const MJsonNode *params)
 
static MJsonNode * js_hs_image_retrieve (const MJsonNode *params)
 
static MJsonNode * js_el_retrieve (const MJsonNode *params)
 
static MJsonNode * js_el_query (const MJsonNode *params)
 
static MJsonNode * js_el_delete (const MJsonNode *params)
 
static MJsonNode * jrpc_cxx (const MJsonNode *params)
 
static MJsonNode * jrpc_old (const MJsonNode *params)
 
static MJsonNode * brpc_cxx (const MJsonNode *params)
 
static MJsonNode * brpc_old (const MJsonNode *params)
 
static MJsonNode * js_cm_transition (const MJsonNode *params)
 
static const EVENT_HEADERCopyEvent (const EVENT_HEADER *pevent)
 
static void StashEvent (const std::string buffer_name, int event_id, int trigger_mask, const EVENT_HEADER *pevent)
 
static void MatchEvent (const std::string buffer_name, const EVENT_HEADER *pevent)
 
static void DeleteEventStash ()
 
static const EVENT_HEADERFindEvent (const std::string buffer_name, int event_id, int trigger_mask, int last_event_id, int last_trigger_mask, DWORD last_serial_number, DWORD last_time_stamp)
 
static MJsonNode * js_bm_receive_event (const MJsonNode *params)
 
static MJsonNode * js_ss_millitime (const MJsonNode *params)
 
static MJsonNode * get_alarms (const MJsonNode *params)
 
static MJsonNode * js_make_subdir (const MJsonNode *params)
 
static MJsonNode * js_ext_list_files (const MJsonNode *params)
 
static MJsonNode * js_ext_save_file (const MJsonNode *params)
 
static MJsonNode * js_ext_read_file (const MJsonNode *params)
 
static MJsonNode * js_read_binary_file (const MJsonNode *params)
 
static MJsonNode * get_debug (const MJsonNode *params)
 
static MJsonNode * set_debug (const MJsonNode *params)
 
static MJsonNode * get_sleep (const MJsonNode *params)
 
static MJsonNode * set_sleep (const MJsonNode *params)
 
static MJsonNode * get_time (const MJsonNode *params)
 
static MJsonNode * set_time (const MJsonNode *params)
 
static MJsonNode * get_schema (const MJsonNode *params)
 
static MJsonNode * js_get_timezone (const MJsonNode *params)
 
void mjsonrpc_add_handler (const char *method, mjsonrpc_handler_t *handler, bool needs_locking)
 
void mjsonrpc_set_std_mutex (void *mutex)
 
void mjsonrpc_init ()
 
void mjsonrpc_exit ()
 
static MJsonNode * mjsonrpc_make_schema (MethodsTable *h)
 
MJsonNode * mjsonrpc_get_schema ()
 
static std::string indent (int x, const char *p=" ")
 
static std::string mjsonrpc_schema_to_html_anything (const MJsonNode *schema, int nest_level, NestedOutput *o)
 
static std::string mjsonrpc_schema_to_html_object (const MJsonNode *schema, int nest_level, NestedOutput *o)
 
static std::string mjsonrpc_schema_to_html_array (const MJsonNode *schema, int nest_level, NestedOutput *o)
 
std::string mjsonrpc_schema_to_text (const MJsonNode *schema)
 
static void add (std::string *s, const char *text)
 
static MJsonNode * mjsonrpc_handle_request (const MJsonNode *request)
 
MJsonNode * mjsonrpc_decode_post_data (const char *post_data)
 

Variables

int mjsonrpc_debug = 0
 
static int mjsonrpc_sleep = 0
 
static int mjsonrpc_time = 0
 
static MJsonNode * gNullNode = NULL
 
static MhiMap gHistoryChannels
 
static std::mutex gEventStashMutex
 
static std::vector< EventStashEntry * > gEventStash
 
static MethodsTable gMethodsTable
 
static std::mutex * gMutex = NULL
 

Typedef Documentation

◆ MethodsTable

typedef std::map<std::string, MethodsTableEntry> MethodsTable

Definition at line 4729 of file mjsonrpc.cxx.

◆ MethodsTableIterator

typedef MethodsTable::iterator MethodsTableIterator

Definition at line 4730 of file mjsonrpc.cxx.

◆ MhiMap

typedef std::map<std::string,MidasHistoryInterface*> MhiMap

Definition at line 1682 of file mjsonrpc.cxx.

Function Documentation

◆ add()

static void add ( std::string *  s,
const char *  text 
)
static

Definition at line 5197 of file mjsonrpc.cxx.

5198{
5199 assert(s != NULL);
5200 if (s->length() > 0)
5201 *s += ", ";
5202 *s += text;
5203}

◆ brpc_cxx()

static MJsonNode * brpc_cxx ( const MJsonNode *  params)
static

Definition at line 3467 of file mjsonrpc.cxx.

3468{
3469 if (!params) {
3470 MJSO* doc = MJSO::I();
3471 doc->D("make RPC call into frontend program via RPC_BRPC_CXX");
3472 doc->P("client_name", MJSON_STRING, "Connect to this MIDAS client, see cm_connect_client()");
3473 doc->P("cmd", MJSON_STRING, "Command passed to client");
3474 doc->P("args", MJSON_STRING, "Parameters passed to client as a string, could be JSON encoded");
3475 doc->R("reply", MJSON_STRING, "Reply from client as a string, could be JSON encoded");
3476 doc->R("status", MJSON_INT, "return status of cm_connect_client() and rpc_client_call()");
3477 return doc;
3478 }
3479
3480 MJsonNode* error = NULL;
3481
3482 std::string name = mjsonrpc_get_param(params, "client_name", &error)->GetString(); if (error) return error;
3483 std::string cmd = mjsonrpc_get_param(params, "cmd", &error)->GetString(); if (error) return error;
3484 std::string args = mjsonrpc_get_param(params, "args", &error)->GetString(); if (error) return error;
3485
3486 int status;
3487
3488 HNDLE hconn;
3489
3490 status = cm_connect_client(name.c_str(), &hconn);
3491
3492 if (status != RPC_SUCCESS) {
3493 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3494 }
3495
3496 std::vector<char> *pbuf = new std::vector<char>;
3497
3498 status = rpc_client_call(hconn, RPC_BRPC_CXX, cmd.c_str(), args.c_str(), pbuf);
3499
3500 // disconnect return status ignored on purpose.
3501 // disconnect not needed, there is no limit on number
3502 // of connections. dead and closed connections are reaped
3503 // automatically. K.O. Feb 2021.
3504 // cm_disconnect_client(hconn, FALSE);
3505
3506 if (status != RPC_SUCCESS) {
3507 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3508 }
3509
3510 return MJsonNode::MakeArrayBuffer(pbuf);
3511}
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2838
#define RPC_SUCCESS
Definition midas.h:699
void D(const char *description)
Definition mjsonrpc.cxx:303
void P(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:340
MJsonNode * mjsonrpc_make_result(MJsonNode *node)
Definition mjsonrpc.cxx:135
static MJSO * I()
Definition mjsonrpc.cxx:298
const MJsonNode * mjsonrpc_get_param(const MJsonNode *params, const char *name, MJsonNode **error)
Definition mjsonrpc.cxx:178
void R(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:348
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:14028
#define RPC_BRPC_CXX
Definition mrpc.h:137
INT HNDLE
Definition midas.h:132
#define name(x)
Definition midas_macro.h:24
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ brpc_old()

static MJsonNode * brpc_old ( const MJsonNode *  params)
static

Definition at line 3513 of file mjsonrpc.cxx.

3514{
3515 if (!params) {
3516 MJSO* doc = MJSO::I();
3517 doc->D("make RPC call into frontend program via RPC_BRPC");
3518 doc->P("client_name", MJSON_STRING, "Connect to this MIDAS client, see cm_connect_client()");
3519 doc->P("cmd", MJSON_STRING, "Command passed to client");
3520 doc->P("args", MJSON_STRING, "Parameters passed to client as a string, could be JSON encoded");
3521 doc->P("max_reply_length?", MJSON_INT, "Optional maximum length of client reply. MIDAS RPC does not support returning data of arbitrary length, maximum length has to be known ahead of time.");
3522 doc->R("reply", MJSON_STRING, "Reply from client as a string, could be JSON encoded");
3523 doc->R("status", MJSON_INT, "return status of cm_connect_client() and rpc_client_call()");
3524 return doc;
3525 }
3526
3527 MJsonNode* error = NULL;
3528
3529 std::string name = mjsonrpc_get_param(params, "client_name", &error)->GetString(); if (error) return error;
3530 std::string cmd = mjsonrpc_get_param(params, "cmd", &error)->GetString(); if (error) return error;
3531 std::string args = mjsonrpc_get_param(params, "args", &error)->GetString(); if (error) return error;
3532 int max_reply_length = mjsonrpc_get_param(params, "max_reply_length", NULL)->GetInt();
3533
3534 int status;
3535
3536 int buf_length = 1024;
3537
3538 if (max_reply_length > buf_length)
3539 buf_length = max_reply_length;
3540
3541 char* buf = (char*)malloc(buf_length);
3542
3543 if (buf == NULL) {
3544 return mjsonrpc_make_error(-32602, "Invalid params", msprintf("malloc(%d) failed, likely invalid max_reply_length value %d", buf_length, max_reply_length).c_str());
3545 }
3546
3547 buf[0] = 0;
3548
3549 HNDLE hconn;
3550
3551 status = cm_connect_client(name.c_str(), &hconn);
3552
3553 if (status != RPC_SUCCESS) {
3554 free(buf);
3555 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3556 }
3557
3558 status = rpc_client_call(hconn, RPC_BRPC, cmd.c_str(), args.c_str(), buf, &buf_length);
3559
3560 // disconnect return status ignored on purpose.
3561 // disconnect not needed, there is no limit on number
3562 // of connections. dead and closed connections are reaped
3563 // automatically. K.O. Feb 2021.
3564 // cm_disconnect_client(hconn, FALSE);
3565
3566 if (status != RPC_SUCCESS) {
3567 free(buf);
3568 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3569 }
3570
3571 return MJsonNode::MakeArrayBuffer(buf, buf_length);
3572}
MJsonNode * mjsonrpc_make_error(int code, const char *message, const char *data)
Definition mjsonrpc.cxx:123
#define RPC_BRPC
Definition mrpc.h:135
std::string msprintf(const char *format,...)
Definition midas.cxx:419
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CopyEvent()

static const EVENT_HEADER * CopyEvent ( const EVENT_HEADER pevent)
static

Definition at line 3640 of file mjsonrpc.cxx.

3641{
3642 size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
3643 //size_t total_size = ALIGN8(event_size);
3644 EVENT_HEADER* ptr = (EVENT_HEADER*)malloc(event_size);
3645 assert(ptr);
3646 memcpy(ptr, pevent, event_size);
3647 return ptr;
3648}
int event_size
Definition msysmon.cxx:527
DWORD data_size
Definition midas.h:857
Here is the caller graph for this function:

◆ DeleteEventStash()

static void DeleteEventStash ( )
static

Definition at line 3728 of file mjsonrpc.cxx.

3729{
3730 std::lock_guard<std::mutex> guard(gEventStashMutex);
3731 for (size_t i=0; i<gEventStash.size(); i++) {
3732 if (gEventStash[i]) {
3733 delete gEventStash[i];
3734 gEventStash[i] = NULL;
3735 }
3736 }
3737}
INT i
Definition mdump.cxx:32
static std::vector< EventStashEntry * > gEventStash
static std::mutex gEventStashMutex
Here is the caller graph for this function:

◆ exec_script()

static MJsonNode * exec_script ( const MJsonNode *  params)
static

Definition at line 516 of file mjsonrpc.cxx.

517{
518 if (!params) {
519 MJSO* doc = MJSO::I();
520 doc->D("execute custom script defined in ODB /Script (scripts show in the menu) or /CustomScript (scripts from custom pages)");
521 doc->P("script?", MJSON_STRING, "Execute ODB /Script/xxx");
522 doc->P("customscript?", MJSON_STRING, "Execute ODB /CustomScript/xxx");
523 doc->R("status", MJSON_INT, "return status of cm_exec_script()");
524 return doc;
525 }
526
527 std::string script = mjsonrpc_get_param(params, "script", NULL)->GetString();
528 std::string customscript = mjsonrpc_get_param(params, "customscript", NULL)->GetString();
529
530 std::string path;
531
532 if (script.length() > 0) {
533 path += "/Script";
534 path += "/";
535 path += script;
536 } else if (customscript.length() > 0) {
537 path += "/CustomScript";
538 path += "/";
539 path += customscript;
540 }
541
542 int status = 0;
543
544 if (path.length() > 0) {
545 status = cm_exec_script(path.c_str());
546 }
547
548 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
549}
int cm_exec_script(const char *odb_path_to_script)
Definition midas.cxx:5535
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindEvent()

static const EVENT_HEADER * FindEvent ( const std::string  buffer_name,
int  event_id,
int  trigger_mask,
int  last_event_id,
int  last_trigger_mask,
DWORD  last_serial_number,
DWORD  last_time_stamp 
)
static

Definition at line 3739 of file mjsonrpc.cxx.

3740{
3741 std::lock_guard<std::mutex> guard(gEventStashMutex);
3742 for (EventStashEntry* s : gEventStash) {
3743 if (s->buffer_name != buffer_name)
3744 continue;
3745 if (bm_match_event(event_id, trigger_mask, s->pevent)) {
3746 if (s->pevent->event_id == last_event_id
3747 && s->pevent->trigger_mask == last_trigger_mask
3748 && s->pevent->serial_number == last_serial_number
3749 && s->pevent->time_stamp == last_time_stamp) {
3750 //s->Print(); printf(", already sent for %d,0x%x\n", event_id, trigger_mask);
3751 return NULL;
3752 } else {
3753 //s->Print(); printf(", serving for %d,0x%x\n", event_id, trigger_mask);
3754 return CopyEvent(s->pevent);
3755 }
3756 }
3757 }
3758 return NULL;
3759}
INT bm_match_event(short int event_id, short int trigger_mask, const EVENT_HEADER *pevent)
Definition midas.cxx:6087
char buffer_name[NAME_LENGTH]
Definition mevb.cxx:45
#define trigger_mask
#define event_id
static const EVENT_HEADER * CopyEvent(const EVENT_HEADER *pevent)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_alarms()

static MJsonNode * get_alarms ( const MJsonNode *  params)
static

Definition at line 3947 of file mjsonrpc.cxx.

3948{
3949 if (!params) {
3950 MJSO* doc = MJSO::I();
3951 doc->D("get alarm data");
3952 doc->P("get_all?", MJSON_BOOL, "get all alarms, even in alarm system not active and alarms not triggered");
3953 doc->R("status", MJSON_INT, "return status of midas library calls");
3954 doc->R("alarm_system_active", MJSON_BOOL, "value of ODB \"/Alarms/alarm system active\"");
3955 doc->R("alarms", MJSON_OBJECT, "alarm data, keyed by alarm name");
3956 doc->R("alarms[].triggered", MJSON_BOOL, "alarm is triggered");
3957 doc->R("alarms[].active", MJSON_BOOL, "alarm is enabled");
3958 doc->R("alarms[].class", MJSON_STRING, "alarm class");
3959 doc->R("alarms[].type", MJSON_INT, "alarm type AT_xxx");
3960 doc->R("alarms[].bgcolor", MJSON_STRING, "display background color");
3961 doc->R("alarms[].fgcolor", MJSON_STRING, "display foreground color");
3962 doc->R("alarms[].message", MJSON_STRING, "alarm ODB message field");
3963 doc->R("alarms[].condition", MJSON_STRING, "alarm ODB condition field");
3964 doc->R("alarms[].evaluated_value?", MJSON_STRING, "evaluated alarm condition (AT_EVALUATED alarms only)");
3965 doc->R("alarms[].periodic_next_time?", MJSON_STRING, "next time the periodic alarm will fire (AT_PERIODIC alarms only)");
3966 doc->R("alarms[].time_triggered_first", MJSON_STRING, "time when alarm was triggered");
3967 doc->R("alarms[].show_to_user", MJSON_STRING, "final alarm text shown to user by mhttpd");
3968 return doc;
3969 }
3970
3971 //MJsonNode* error = NULL;
3972
3973 bool get_all = mjsonrpc_get_param(params, "get_all", NULL)->GetBool();
3974
3975 int status;
3976 HNDLE hDB;
3977
3979
3980 if (status != DB_SUCCESS) {
3981 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3982 }
3983
3984 int flag;
3985 int size;
3986 int alarm_system_active = 0;
3987
3988 /* check global alarm flag */
3989 flag = TRUE;
3990 size = sizeof(flag);
3991 status = db_get_value(hDB, 0, "/Alarms/Alarm System active", &flag, &size, TID_BOOL, TRUE);
3992
3993 if (status != DB_SUCCESS) {
3994 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3995 }
3996
3997 alarm_system_active = flag;
3998
3999 if (!alarm_system_active)
4000 if (!get_all) {
4001 return mjsonrpc_make_result("status", MJsonNode::MakeInt(SUCCESS),
4002 "alarm_system_active", MJsonNode::MakeBool(alarm_system_active!=0),
4003 "alarms", MJsonNode::MakeObject());
4004 }
4005
4006 /* go through all alarms */
4007 HNDLE hkey;
4008 status = db_find_key(hDB, 0, "/Alarms/Alarms", &hkey);
4009
4010 if (status != DB_SUCCESS) {
4011 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
4012 }
4013
4014 MJsonNode* alarms = MJsonNode::MakeObject();
4015
4016 for (int i = 0;; i++) {
4017 HNDLE hsubkey;
4018 KEY key;
4019
4020 db_enum_link(hDB, hkey, i, &hsubkey);
4021
4022 if (!hsubkey)
4023 break;
4024
4025 status = db_get_key(hDB, hsubkey, &key);
4026
4027 const char* name = key.name;
4028
4029 flag = 0;
4030 size = sizeof(flag);
4031 status = db_get_value(hDB, hsubkey, "Triggered", &flag, &size, TID_INT, TRUE);
4032
4033 // skip un-triggered alarms
4034 if (!flag)
4035 if (!get_all)
4036 continue;
4037
4038 MJsonNode* a = MJsonNode::MakeObject();
4039
4040 a->AddToObject("triggered", MJsonNode::MakeBool(flag!=0));
4041
4042 flag = 1;
4043 size = sizeof(BOOL);
4044 status = db_get_value(hDB, hsubkey, "Active", &flag, &size, TID_BOOL, FALSE);
4045
4046 a->AddToObject("active", MJsonNode::MakeBool(flag!=0));
4047
4048 std::string alarm_class{"Alarm"};
4049
4050 db_get_value_string(hDB, hsubkey, "Alarm Class", 0, &alarm_class);
4051
4052 ss_repair_utf8(alarm_class);
4053
4054 a->AddToObject("class", MJsonNode::MakeString(alarm_class.c_str()));
4055
4056 int atype = 0;
4057 size = sizeof(atype);
4058 db_get_value(hDB, hsubkey, "Type", &atype, &size, TID_INT, FALSE);
4059
4060 a->AddToObject("type", MJsonNode::MakeInt(atype));
4061
4062 std::string bgcol{"red"};
4063
4064 if (alarm_class.length() > 0) {
4065 std::string path = msprintf("/Alarms/Classes/%s/Display BGColor", alarm_class.c_str());
4066 db_get_value_string(hDB, 0, path.c_str(), 0, &bgcol);
4067 }
4068
4069 ss_repair_utf8(bgcol);
4070
4071 a->AddToObject("bgcolor", MJsonNode::MakeString(bgcol.c_str()));
4072
4073 std::string fgcol{"black"};
4074
4075 if (alarm_class.length() > 0) {
4076 std::string path = msprintf("/Alarms/Classes/%s/Display FGColor", alarm_class.c_str());
4077 db_get_value_string(hDB, 0, path.c_str(), 0, &fgcol);
4078 }
4079
4080 ss_repair_utf8(fgcol);
4081
4082 a->AddToObject("fgcolor", MJsonNode::MakeString(fgcol.c_str()));
4083
4084 flag = 1;
4085 if (alarm_class.length() > 0) {
4086 size = sizeof(BOOL);
4087 std::string path = msprintf("/Alarms/Classes/%s/Alarm sound", alarm_class.c_str());
4088 db_get_value(hDB, 0, path.c_str(), &flag, &size, TID_BOOL, FALSE);
4089 }
4090
4091 a->AddToObject("alarm_sound", MJsonNode::MakeBool(flag!=0));
4092
4093 std::string msg;
4094 db_get_value_string(hDB, hsubkey, "Alarm Message", 0, &msg);
4095
4096 ss_repair_utf8(msg);
4097
4098 a->AddToObject("message", MJsonNode::MakeString(msg.c_str()));
4099
4100 std::string cond;
4101 db_get_value_string(hDB, hsubkey, "Condition", 0, &cond);
4102
4103 ss_repair_utf8(cond);
4104
4105 a->AddToObject("condition", MJsonNode::MakeString(cond.c_str()));
4106
4107 std::string show_to_user;
4108
4109 if (atype == AT_EVALUATED) {
4110 /* retrieve value */
4111 std::string value;
4112 al_evaluate_condition(name, cond.c_str(), &value);
4113 show_to_user = msprintf(msg.c_str(), value.c_str());
4115 a->AddToObject("evaluated_value", MJsonNode::MakeString(value.c_str()));
4116 } else
4117 show_to_user = msg;
4118
4119 ss_repair_utf8(show_to_user);
4120
4121 a->AddToObject("show_to_user", MJsonNode::MakeString(show_to_user.c_str()));
4122
4123 std::string triggered_first;
4124 status = db_get_value_string(hDB, hsubkey, "Time triggered first", 0, &triggered_first);
4125
4126 ss_repair_utf8(triggered_first);
4127
4128 a->AddToObject("time_triggered_first", MJsonNode::MakeString(triggered_first.c_str()));
4129
4130 if (atype == AT_PERIODIC) {
4131 DWORD last = 0;
4132 size = sizeof(last);
4133 db_get_value(hDB, hsubkey, "Checked last", &last, &size, TID_DWORD, FALSE);
4134
4135 if (last == 0) {
4136 last = ss_time();
4137 db_set_value(hDB, hsubkey, "Checked last", &last, size, 1, TID_DWORD);
4138 }
4139
4140 int interval = 0;
4141 size = sizeof(interval);
4142 db_get_value(hDB, hsubkey, "Check interval", &interval, &size, TID_INT, FALSE);
4143
4144 time_t tnext = last + interval;
4145
4146 char ctimebuf[32];
4147 ctime_r(&tnext, ctimebuf);
4148
4149 //ss_repair_utf8(ctimebuf); redundant!
4150
4151 a->AddToObject("periodic_next_time", MJsonNode::MakeString(ctimebuf));
4152 }
4153
4154 alarms->AddToObject(name, a);
4155 }
4156
4157 return mjsonrpc_make_result("status", MJsonNode::MakeInt(SUCCESS),
4158 "alarm_system_active", MJsonNode::MakeBool(alarm_system_active!=0),
4159 "alarms", alarms);
4160}
#define FALSE
Definition cfortran.h:309
BOOL al_evaluate_condition(const char *alarm_name, const char *condition, std::string *pvalue)
Definition alarm.cxx:259
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3083
#define DB_SUCCESS
Definition midas.h:632
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define TID_BOOL
Definition midas.h:340
#define TID_INT
Definition midas.h:338
#define TID_DWORD
Definition midas.h:336
DWORD ss_time()
Definition system.cxx:3541
bool ss_repair_utf8(char *string)
Definition system.cxx:8236
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5680
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6538
INT EXPRT db_get_value_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int index, std::string *s, BOOL create, int create_string_length)
Definition odb.cxx:14528
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5990
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5523
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4751
HNDLE hDB
main ODB handle
Definition mana.cxx:207
KEY key
Definition mdump.cxx:34
DWORD BOOL
Definition midas.h:105
#define AT_PERIODIC
Definition midas.h:1444
#define TRUE
Definition midas.h:182
#define AT_EVALUATED
Definition midas.h:1443
double value[100]
Definition odbhist.cxx:42
Definition midas.h:1027
char name[NAME_LENGTH]
Definition midas.h:1030
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_debug()

static MJsonNode * get_debug ( const MJsonNode *  params)
static

Definition at line 4600 of file mjsonrpc.cxx.

4601{
4602 if (!params) {
4603 MJSO *doc = MJSO::I();
4604 doc->D("get current value of mjsonrpc_debug");
4605 doc->P(NULL, 0, "there are no input parameters");
4606 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_debug");
4607 return doc;
4608 }
4609
4610 return mjsonrpc_make_result("debug", MJsonNode::MakeInt(mjsonrpc_debug));
4611}
int mjsonrpc_debug
Definition mjsonrpc.cxx:112
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_schema()

static MJsonNode * get_schema ( const MJsonNode *  params)
static

Definition at line 4681 of file mjsonrpc.cxx.

4682{
4683 if (!params) {
4684 MJSO* doc = MJSO::I();
4685 doc->D("Get the MIDAS JSON-RPC schema JSON object");
4686 doc->P(NULL, 0, "there are no input parameters");
4687 doc->R(NULL, MJSON_OBJECT, "returns the MIDAS JSON-RPC schema JSON object");
4688 return doc;
4689 }
4690
4692}
MJsonNode * mjsonrpc_get_schema()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_sleep()

static MJsonNode * get_sleep ( const MJsonNode *  params)
static

Definition at line 4627 of file mjsonrpc.cxx.

4628{
4629 if (!params) {
4630 MJSO *doc = MJSO::I();
4631 doc->D("get current value of mjsonrpc_sleep");
4632 doc->P(NULL, 0, "there are no input parameters");
4633 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_sleep");
4634 return doc;
4635 }
4636
4637 return mjsonrpc_make_result("sleep", MJsonNode::MakeInt(mjsonrpc_sleep));
4638}
static int mjsonrpc_sleep
Definition mjsonrpc.cxx:113
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_time()

static MJsonNode * get_time ( const MJsonNode *  params)
static

Definition at line 4654 of file mjsonrpc.cxx.

4655{
4656 if (!params) {
4657 MJSO *doc = MJSO::I();
4658 doc->D("get current value of mjsonrpc_time");
4659 doc->P(NULL, 0, "there are no input parameters");
4660 doc->R(NULL, MJSON_INT, "current value of mjsonrpc_time");
4661 return doc;
4662 }
4663
4664 return mjsonrpc_make_result("time", MJsonNode::MakeInt(mjsonrpc_time));
4665}
static int mjsonrpc_time
Definition mjsonrpc.cxx:114
Here is the call graph for this function:

◆ GetHistory()

static MidasHistoryInterface * GetHistory ( const char *  name)
static

Definition at line 1686 of file mjsonrpc.cxx.

1687{
1688 // empty name means use the default reader channel
1689
1690 MhiMap::iterator ci = gHistoryChannels.find(name);
1691 if (ci != gHistoryChannels.end()) {
1692 return ci->second;
1693 };
1694
1695 int verbose = 0;
1696
1697 HNDLE hDB;
1699
1700 HNDLE hKey = 0;
1701
1702 if (strlen(name) < 1) {
1704 if (status != HS_SUCCESS) {
1705 return NULL;
1706 }
1707 } else {
1708 HNDLE hKeyChan;
1709 int status = db_find_key(hDB, 0, "/Logger/History", &hKeyChan);
1710 if (status != DB_SUCCESS) {
1711 return NULL;
1712 }
1713 status = db_find_key(hDB, hKeyChan, name, &hKey);
1714 if (status != DB_SUCCESS) {
1715 return NULL;
1716 }
1717 }
1718
1719 MidasHistoryInterface* mh = NULL;
1720
1722 if (status != HS_SUCCESS || mh==NULL) {
1723 cm_msg(MERROR, "GetHistory", "Cannot configure history, hs_get_history() status %d", status);
1724 return NULL;
1725 }
1726
1727 //printf("hs_get_history: \"%s\" -> mh %p\n", name, mh);
1728
1730
1731 // cm_msg(MINFO, "GetHistory", "Reading history channel \"%s\" from channel \'%s\' type \'%s\'", name, mh->name, mh->type);
1732
1733 return mh;
1734}
#define HS_SUCCESS
Definition midas.h:728
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:939
#define HS_GET_INACTIVE
Definition history.h:37
#define HS_GET_READER
Definition history.h:35
int hs_find_reader_channel(HNDLE hDB, HNDLE *hKeyOut, int debug_flag)
int hs_get_history(HNDLE hDB, HNDLE hKey, int flags, int debug_flag, MidasHistoryInterface **mh)
HNDLE hKey
BOOL verbose
Definition mana.cxx:255
MidasHistoryInterface * mh
static MhiMap gHistoryChannels
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTimeSec()

static double GetTimeSec ( )
static

Definition at line 116 of file mjsonrpc.cxx.

117{
118 struct timeval tv;
119 gettimeofday(&tv, NULL);
120 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
121}
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition msysmon.cxx:1095
Here is the call graph for this function:
Here is the caller graph for this function:

◆ indent()

static std::string indent ( int  x,
const char *  p = " " 
)
static

Definition at line 4891 of file mjsonrpc.cxx.

4892{
4893 if (x<1)
4894 return "";
4895 std::string s;
4896 for (int i=0; i<x; i++)
4897 s += p;
4898 return s;
4899}
Here is the caller graph for this function:

◆ jrpc_cxx()

static MJsonNode * jrpc_cxx ( const MJsonNode *  params)
static

Definition at line 3345 of file mjsonrpc.cxx.

3346{
3347 if (!params) {
3348 MJSO* doc = MJSO::I();
3349 doc->D("make RPC call into frontend program via RPC_JRPC_CXX");
3350 doc->P("client_name", MJSON_STRING, "Connect to this MIDAS client, see cm_connect_client()");
3351 doc->P("cmd", MJSON_STRING, "Command passed to client");
3352 doc->P("args", MJSON_STRING, "Parameters passed to client as a string, could be JSON encoded");
3353 doc->R("reply", MJSON_STRING, "Reply from client as a string, could be JSON encoded");
3354 doc->R("status", MJSON_INT, "return status of cm_connect_client() and rpc_client_call()");
3355 return doc;
3356 }
3357
3358 MJsonNode* error = NULL;
3359
3360 std::string name = mjsonrpc_get_param(params, "client_name", &error)->GetString(); if (error) return error;
3361 std::string cmd = mjsonrpc_get_param(params, "cmd", &error)->GetString(); if (error) return error;
3362 std::string args = mjsonrpc_get_param(params, "args", &error)->GetString(); if (error) return error;
3363
3364 int status;
3365
3366 HNDLE hconn;
3367
3368 status = cm_connect_client(name.c_str(), &hconn);
3369
3370 if (status != RPC_SUCCESS) {
3371 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3372 }
3373
3374 std::string reply;
3375
3376 status = rpc_client_call(hconn, RPC_JRPC_CXX, cmd.c_str(), args.c_str(), &reply);
3377
3378 // disconnect return status ignored on purpose.
3379 // disconnect not needed, there is no limit on number
3380 // of connections. dead and closed connections are reaped
3381 // automatically. K.O. Feb 2021.
3382 // cm_disconnect_client(hconn, FALSE);
3383
3384 if (status != RPC_SUCCESS) {
3385 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3386 }
3387
3388 ss_repair_utf8(reply);
3389
3390 MJsonNode* rn = MJsonNode::MakeString(reply.c_str());
3391
3392 return mjsonrpc_make_result("reply", rn, "status", MJsonNode::MakeInt(SUCCESS));
3393}
#define RPC_JRPC_CXX
Definition mrpc.h:136
INT rn
Definition mstat.cxx:30
Here is the call graph for this function:
Here is the caller graph for this function:

◆ jrpc_old()

static MJsonNode * jrpc_old ( const MJsonNode *  params)
static

Definition at line 3395 of file mjsonrpc.cxx.

3396{
3397 if (!params) {
3398 MJSO* doc = MJSO::I();
3399 doc->D("make RPC call into frontend program via RPC_JRPC");
3400 doc->P("client_name", MJSON_STRING, "Connect to this MIDAS client, see cm_connect_client()");
3401 doc->P("cmd", MJSON_STRING, "Command passed to client");
3402 doc->P("args", MJSON_STRING, "Parameters passed to client as a string, could be JSON encoded");
3403 doc->P("max_reply_length?", MJSON_INT, "Optional maximum length of client reply. MIDAS RPC does not support returning strings of arbitrary length, maximum length has to be known ahead of time.");
3404 doc->R("reply", MJSON_STRING, "Reply from client as a string, could be JSON encoded");
3405 doc->R("status", MJSON_INT, "return status of cm_connect_client() and rpc_client_call()");
3406 return doc;
3407 }
3408
3409 MJsonNode* error = NULL;
3410
3411 std::string name = mjsonrpc_get_param(params, "client_name", &error)->GetString(); if (error) return error;
3412 std::string cmd = mjsonrpc_get_param(params, "cmd", &error)->GetString(); if (error) return error;
3413 std::string args = mjsonrpc_get_param(params, "args", &error)->GetString(); if (error) return error;
3414 int max_reply_length = mjsonrpc_get_param(params, "max_reply_length", NULL)->GetInt();
3415
3416 int status;
3417
3418 int buf_length = 1024;
3419
3420 if (max_reply_length > buf_length)
3421 buf_length = max_reply_length;
3422
3423 char* buf = (char*)malloc(buf_length);
3424
3425 if (buf == NULL) {
3426 return mjsonrpc_make_error(-32602, "Invalid params", msprintf("malloc(%d) failed, likely invalid max_reply_length value %d", buf_length, max_reply_length).c_str());
3427 }
3428
3429 buf[0] = 0;
3430
3431 HNDLE hconn;
3432
3433 status = cm_connect_client(name.c_str(), &hconn);
3434
3435 if (status != RPC_SUCCESS) {
3436 free(buf);
3437 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3438 }
3439
3440 status = rpc_client_call(hconn, RPC_JRPC, cmd.c_str(), args.c_str(), buf, buf_length);
3441
3442 // disconnect return status ignored on purpose.
3443 // disconnect not needed, there is no limit on number
3444 // of connections. dead and closed connections are reaped
3445 // automatically. K.O. Feb 2021.
3446 // cm_disconnect_client(hconn, FALSE);
3447
3448 if (status != RPC_SUCCESS) {
3449 free(buf);
3450 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3451 }
3452
3453 ss_repair_utf8(buf);
3454
3455 MJsonNode* reply = MJsonNode::MakeString(buf);
3456 free(buf);
3457
3458 return mjsonrpc_make_result("reply", reply, "status", MJsonNode::MakeInt(SUCCESS));
3459}
#define RPC_JRPC
Definition mrpc.h:134
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_al_reset_alarm()

static MJsonNode * js_al_reset_alarm ( const MJsonNode *  params)
static

Definition at line 1576 of file mjsonrpc.cxx.

1577{
1578 if (!params) {
1579 MJSO* doc = MJSO::I();
1580 doc->D("reset alarms");
1581 doc->P("alarms[]", MJSON_STRING, "array of alarm names");
1582 doc->R("status[]", MJSON_INT, "return status of al_reset_alarm() for each alarm");
1583 return doc;
1584 }
1585
1586 MJsonNode* error = NULL;
1587
1588 const MJsonNodeVector* alarms = mjsonrpc_get_param_array(params, "alarms", &error); if (error) return error;
1589
1590 MJsonNode* sresult = MJsonNode::MakeArray();
1591
1592 for (unsigned i=0; i<alarms->size(); i++) {
1593 int status = al_reset_alarm((*alarms)[i]->GetString().c_str());
1594 sresult->AddToArray(MJsonNode::MakeInt(status));
1595 }
1596
1597 return mjsonrpc_make_result("status", sresult);
1598}
INT al_reset_alarm(const char *alarm_name)
Definition alarm.cxx:605
const MJsonNodeVector * mjsonrpc_get_param_array(const MJsonNode *params, const char *name, MJsonNode **error)
Definition mjsonrpc.cxx:201
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_al_trigger_alarm()

static MJsonNode * js_al_trigger_alarm ( const MJsonNode *  params)
static

Definition at line 1600 of file mjsonrpc.cxx.

1601{
1602 if (!params) {
1603 MJSO* doc = MJSO::I();
1604 doc->D("trigger an alarm");
1605 doc->P("name", MJSON_STRING, "alarm name");
1606 doc->P("message", MJSON_STRING, "alarm message");
1607 doc->P("class", MJSON_STRING, "alarm class");
1608 doc->P("condition", MJSON_STRING, "alarm condition");
1609 doc->P("type", MJSON_INT, "alarm type (AT_xxx)");
1610 doc->R("status", MJSON_INT, "return status of al_trigger_alarm()");
1611 return doc;
1612 }
1613
1614 MJsonNode* error = NULL;
1615
1616 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString(); if (error) return error;
1617 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1618 std::string xclass = mjsonrpc_get_param(params, "class", &error)->GetString(); if (error) return error;
1619 std::string condition = mjsonrpc_get_param(params, "condition", &error)->GetString(); if (error) return error;
1620 int type = mjsonrpc_get_param(params, "type", &error)->GetInt(); if (error) return error;
1621
1622 int status = al_trigger_alarm(name.c_str(), message.c_str(), xclass.c_str(), condition.c_str(), type);
1623
1624 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1625}
INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
Definition alarm.cxx:396
INT type
Definition mana.cxx:269
#define message(type, str)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_al_trigger_class()

static MJsonNode * js_al_trigger_class ( const MJsonNode *  params)
static

Definition at line 1627 of file mjsonrpc.cxx.

1628{
1629 if (!params) {
1630 MJSO* doc = MJSO::I();
1631 doc->D("trigger an alarm");
1632 doc->P("class", MJSON_STRING, "alarm class");
1633 doc->P("message", MJSON_STRING, "alarm message");
1634 doc->P("first?", MJSON_BOOL, "see al_trigger_class() in midas.c");
1635 doc->R("status", MJSON_INT, "return status of al_trigger_class()");
1636 return doc;
1637 }
1638
1639 MJsonNode* error = NULL;
1640
1641 std::string xclass = mjsonrpc_get_param(params, "class", &error)->GetString(); if (error) return error;
1642 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1643 bool first = mjsonrpc_get_param(params, "first", NULL)->GetBool();
1644
1645 int status = al_trigger_class(xclass.c_str(), message.c_str(), first);
1646
1647 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1648}
INT al_trigger_class(const char *alarm_class, const char *alarm_message, BOOL first)
Definition alarm.cxx:499
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_bm_receive_event()

static MJsonNode * js_bm_receive_event ( const MJsonNode *  params)
static

Definition at line 3761 of file mjsonrpc.cxx.

3762{
3763 if (!params) {
3764 MJSO* doc = MJSO::I();
3765 doc->D("read event buffers");
3766 doc->P("buffer_name", MJSON_STRING, "name of event buffer");
3767 doc->P("event_id?", MJSON_INT, "requested event id, -1 means any event id");
3768 doc->P("trigger_mask?", MJSON_INT, "requested trigger mask, -1 means any trigger mask");
3769 doc->P("get_recent?", MJSON_BOOL, "get last available event that matches this event request");
3770 doc->P("last_event_header[]?", MJSON_INT, "do not resend an event we already received: event header of last received event [event_id,trigger_mask,serial_number,time_stamp]");
3771 doc->P("timeout_millisec?", MJSON_NUMBER, "how long to wait for an event");
3772 doc->R("binary data", MJSON_ARRAYBUFFER, "binary event data");
3773 doc->R("status", MJSON_INT, "return status of bm_open_buffer(), bm_request_event(), bm_set_cache_size(), bm_receive_alloc()");
3774 return doc;
3775 }
3776
3777 MJsonNode* error = NULL;
3778
3779 std::string buffer_name = mjsonrpc_get_param(params, "buffer_name", &error)->GetString(); if (error) return error;
3780 int event_id = mjsonrpc_get_param(params, "event_id", NULL)->GetInt();
3781 int trigger_mask = mjsonrpc_get_param(params, "trigger_mask", NULL)->GetInt();
3782 bool get_recent = mjsonrpc_get_param(params, "get_recent", NULL)->GetBool();
3783 const MJsonNodeVector* last_event_header = mjsonrpc_get_param(params, "last_event_header", NULL)->GetArray();
3784 int timeout_millisec = mjsonrpc_get_param(params, "timeout_millisec", NULL)->GetInt();
3785
3786 int last_event_id = 0;
3787 int last_trigger_mask = 0;
3788 int last_serial_number = 0;
3789 int last_time_stamp = 0;
3790
3791 if (last_event_header && last_event_header->size() > 0) {
3792 if (last_event_header->size() != 4) {
3793 return mjsonrpc_make_error(-32602, "Invalid params", "last_event_header should be an array with 4 elements");
3794 }
3795
3796 last_event_id = (*last_event_header)[0]->GetInt();
3797 last_trigger_mask = (*last_event_header)[1]->GetInt();
3798 last_serial_number = (*last_event_header)[2]->GetInt();
3799 last_time_stamp = (*last_event_header)[3]->GetInt();
3800 }
3801
3802 //printf("last event header: %d %d %d %d\n", last_event_id, last_trigger_mask, last_serial_number, last_time_stamp);
3803
3804 if (event_id == 0)
3806
3807 if (trigger_mask == 0)
3809
3810 //printf("js_bm_receive_event: buffer \"%s\", event_id %d, trigger_mask 0x%04x\n", buffer_name.c_str(), event_id, trigger_mask);
3811
3812 int status;
3813
3814 HNDLE buffer_handle = 0;
3815
3816 status = bm_get_buffer_handle(buffer_name.c_str(), &buffer_handle);
3817
3818 if (status != BM_SUCCESS) {
3819 // if buffer not already open, we need to open it,
3820 // but we must hold a lock in case multiple RPC handler threads
3821 // try to open it at the same time. K.O.
3822 static std::mutex gMutex;
3823 std::lock_guard<std::mutex> lock_guard(gMutex); // lock the mutex
3824
3825 // we have the lock. now we check if some other thread
3826 // opened the buffer while we were waiting for the lock. K.O.
3827 status = bm_get_buffer_handle(buffer_name.c_str(), &buffer_handle);
3828
3829 if (status != BM_SUCCESS) {
3830 status = bm_open_buffer(buffer_name.c_str(), 0, &buffer_handle);
3831 if (status != BM_SUCCESS && status != BM_CREATED) {
3832 MJsonNode* result = MJsonNode::MakeObject();
3833 result->AddToObject("status", MJsonNode::MakeInt(status));
3834 return mjsonrpc_make_result(result);
3835 }
3836 status = bm_set_cache_size(buffer_handle, 0, 0);
3837 if (status != BM_SUCCESS) {
3838 MJsonNode* result = MJsonNode::MakeObject();
3839 result->AddToObject("status", MJsonNode::MakeInt(status));
3840 return mjsonrpc_make_result(result);
3841 }
3842 int request_id = 0;
3843 status = bm_request_event(buffer_handle, EVENTID_ALL, TRIGGER_ALL, GET_NONBLOCKING, &request_id, NULL);
3844 if (status != BM_SUCCESS) {
3845 MJsonNode* result = MJsonNode::MakeObject();
3846 result->AddToObject("status", MJsonNode::MakeInt(status));
3847 return mjsonrpc_make_result(result);
3848 }
3849 }
3850 }
3851
3852 if (timeout_millisec <= 0)
3853 timeout_millisec = 100.0;
3854
3855 double start_time = ss_time_sec();
3856 double end_time = start_time + timeout_millisec/1000.0;
3857
3858 // in "GET_RECENT" mode, we read all avialable events from the event buffer
3859 // and save them in the event stash (MatchEvent()), after we empty the event
3860 // buffer (BM_ASYNC_RETURN), we send the last saved event. K.O.
3861
3862 while (1) {
3863 EVENT_HEADER* pevent = NULL;
3864
3865 status = bm_receive_event_alloc(buffer_handle, &pevent, BM_NO_WAIT);
3866
3867 if (status == BM_SUCCESS) {
3868 //printf("got event_id %d, trigger_mask 0x%04x\n", pevent->event_id, pevent->trigger_mask);
3869
3870 if (get_recent) {
3871 if (bm_match_event(event_id, trigger_mask, pevent)) {
3873 } else {
3874 MatchEvent(buffer_name, pevent);
3875 }
3876 free(pevent);
3877 pevent = NULL;
3878 } else {
3879 if (bm_match_event(event_id, trigger_mask, pevent)) {
3881
3882 size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
3883 //size_t total_size = ALIGN8(event_size);
3884 return MJsonNode::MakeArrayBuffer((char*)pevent, event_size);
3885 }
3886
3887 MatchEvent(buffer_name, pevent);
3888
3889 free(pevent);
3890 pevent = NULL;
3891 }
3892 } else if (status == BM_ASYNC_RETURN) {
3893 if (get_recent) {
3894 //printf("bm_async_return!\n");
3895 break;
3896 }
3897 ss_sleep(10);
3898 } else {
3899 MJsonNode* result = MJsonNode::MakeObject();
3900 result->AddToObject("status", MJsonNode::MakeInt(status));
3901 return mjsonrpc_make_result(result);
3902 }
3903
3904 if (ss_time_sec() > end_time) {
3905 //printf("timeout!\n");
3906 break;
3907 }
3908 }
3909
3910 const EVENT_HEADER* pevent = FindEvent(buffer_name, event_id, trigger_mask, last_event_id, last_trigger_mask, last_serial_number, last_time_stamp);
3911 if (pevent) {
3912 size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
3913 //size_t total_size = ALIGN8(event_size);
3914 return MJsonNode::MakeArrayBuffer((char*)pevent, event_size);
3915 }
3916
3917 MJsonNode* result = MJsonNode::MakeObject();
3918 result->AddToObject("status", MJsonNode::MakeInt(BM_ASYNC_RETURN));
3919 return mjsonrpc_make_result(result);
3920}
INT bm_open_buffer(const char *buffer_name, INT buffer_size, INT *buffer_handle)
Definition midas.cxx:6782
INT bm_request_event(HNDLE buffer_handle, short int event_id, short int trigger_mask, INT sampling_type, HNDLE *request_id, EVENT_HANDLER *func)
Definition midas.cxx:8578
INT bm_set_cache_size(INT buffer_handle, size_t read_size, size_t write_size)
Definition midas.cxx:8253
INT bm_get_buffer_handle(const char *buffer_name, INT *buffer_handle)
Definition midas.cxx:7149
INT bm_receive_event_alloc(INT buffer_handle, EVENT_HEADER **ppevent, int timeout_msec)
Definition midas.cxx:10972
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define BM_CREATED
Definition midas.h:606
#define GET_NONBLOCKING
Definition midas.h:322
#define TRIGGER_ALL
Definition midas.h:538
#define BM_NO_WAIT
Definition midas.h:366
#define EVENTID_ALL
Definition midas.h:537
double ss_time_sec()
Definition system.cxx:3546
INT ss_sleep(INT millisec)
Definition system.cxx:3707
static void StashEvent(const std::string buffer_name, int event_id, int trigger_mask, const EVENT_HEADER *pevent)
static std::mutex * gMutex
static const EVENT_HEADER * FindEvent(const std::string buffer_name, int event_id, int trigger_mask, int last_event_id, int last_trigger_mask, DWORD last_serial_number, DWORD last_time_stamp)
static void MatchEvent(const std::string buffer_name, const EVENT_HEADER *pevent)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_exist()

static MJsonNode * js_cm_exist ( const MJsonNode *  params)
static

Definition at line 432 of file mjsonrpc.cxx.

433{
434 if (!params) {
435 MJSO* doc = MJSO::I();
436 doc->D("calls MIDAS cm_exist() to check if given MIDAS program is running");
437 doc->P("name", MJSON_STRING, "name of the program, corresponding to ODB /Programs/name");
438 doc->P("unique?", MJSON_BOOL, "bUnique argument to cm_exist()");
439 doc->R("status", MJSON_INT, "return status of cm_exist()");
440 return doc;
441 }
442
443 MJsonNode* error = NULL;
444
445 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString();
446 if (error)
447 return error;
448
449 int unique = mjsonrpc_get_param(params, "unique", NULL)->GetBool();
450
451 int status = cm_exist(name.c_str(), unique);
452
453 if (mjsonrpc_debug)
454 printf("cm_exist(%s,%d) -> %d\n", name.c_str(), unique, status);
455
456 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
457}
INT cm_exist(const char *name, BOOL bClientName)
Definition midas.cxx:7594
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_msg1()

static MJsonNode * js_cm_msg1 ( const MJsonNode *  params)
static

Definition at line 1497 of file mjsonrpc.cxx.

1498{
1499 if (!params) {
1500 MJSO *doc = MJSO::I();
1501 doc->D("Generate a midas message using cm_msg1()");
1502 doc->P("facility?", MJSON_STRING, "message facility, default is \"midas\"");
1503 doc->P("user?", MJSON_STRING, "message user, default is \"javascript_commands\"");
1504 doc->P("type?", MJSON_INT, "message type, MT_xxx from midas.h, default is MT_INFO");
1505 doc->P("message", MJSON_STRING, "message text");
1506 doc->R("status", MJSON_INT, "return status of cm_msg1()");
1507 return doc;
1508 }
1509
1510 MJsonNode* error = NULL;
1511
1512 std::string facility = mjsonrpc_get_param(params, "facility", NULL)->GetString();
1513 std::string user = mjsonrpc_get_param(params, "user", NULL)->GetString();
1514 int type = mjsonrpc_get_param(params, "type", NULL)->GetInt();
1515 std::string message = mjsonrpc_get_param(params, "message", &error)->GetString(); if (error) return error;
1516
1517 if (facility.size() <1)
1518 facility = "midas";
1519 if (user.size()<1)
1520 user = "javascript_commands";
1521 if (type == 0)
1522 type = MT_INFO;
1523
1524 int status = cm_msg1(type, __FILE__, __LINE__, facility.c_str(), user.c_str(), "%s", message.c_str());
1525
1526 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1527}
#define MT_INFO
Definition midas.h:543
INT cm_msg1(INT message_type, const char *filename, INT line, const char *facility, const char *routine, const char *format,...)
Definition midas.cxx:997
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_msg_facilities()

static MJsonNode * js_cm_msg_facilities ( const MJsonNode *  params)
static

Definition at line 1472 of file mjsonrpc.cxx.

1473{
1474 if (!params) {
1475 MJSO* doc = MJSO::I();
1476 doc->D("get message facilities using cm_msg_facilities()");
1477 doc->R("status", MJSON_INT, "return status of cm_msg_facilities()");
1478 doc->R("facilities[]", MJSON_STRING, "array of facility names");
1479 return doc;
1480 }
1481
1483
1485
1486 MJsonNode* facilities = MJsonNode::MakeArray();
1487
1488 for (unsigned i=0; i<list.size(); i++) {
1490 facilities->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1491 }
1492
1493 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status),
1494 "facilities", facilities);
1495}
INT EXPRT cm_msg_facilities(STRING_LIST *list)
Definition midas.cxx:522
std::vector< std::string > STRING_LIST
Definition midas.h:246
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_msg_retrieve()

static MJsonNode * js_cm_msg_retrieve ( const MJsonNode *  params)
static

Definition at line 1529 of file mjsonrpc.cxx.

1530{
1531 if (!params) {
1532 MJSO *doc = MJSO::I();
1533 doc->D("Retrieve midas messages using cm_msg_retrieve2()");
1534 doc->P("facility?", MJSON_STRING, "message facility, default is \"midas\"");
1535 doc->P("min_messages?", MJSON_INT, "get at least this many messages, default is 1");
1536 doc->P("time?", MJSON_NUMBER, "start from given timestamp, value 0 means give me newest messages, default is 0");
1537 doc->R("num_messages", MJSON_INT, "number of messages returned");
1538 doc->R("messages", MJSON_STRING, "messages separated by \\n");
1539 doc->R("status", MJSON_INT, "return status of cm_msg_retrieve2()");
1540 return doc;
1541 }
1542
1543 std::string facility = mjsonrpc_get_param(params, "facility", NULL)->GetString();
1544 int min_messages = mjsonrpc_get_param(params, "min_messages", NULL)->GetInt();
1545 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1546
1547 if (facility.size() < 1)
1548 facility = "midas";
1549
1550 int num_messages = 0;
1551 char* messages = NULL;
1552
1553 int status = cm_msg_retrieve2(facility.c_str(), (time_t)time, min_messages, &messages, &num_messages);
1554
1555 MJsonNode* result = MJsonNode::MakeObject();
1556
1557 result->AddToObject("status", MJsonNode::MakeInt(status));
1558 result->AddToObject("num_messages", MJsonNode::MakeInt(num_messages));
1559
1560 if (messages) {
1561 ss_repair_utf8(messages);
1562 result->AddToObject("messages", MJsonNode::MakeString(messages));
1563 free(messages);
1564 messages = NULL;
1565 }
1566
1567 return mjsonrpc_make_result(result);
1568}
INT cm_msg_retrieve2(const char *facility, time_t t, INT n_message, char **messages, int *num_messages)
Definition midas.cxx:1311
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_shutdown()

static MJsonNode * js_cm_shutdown ( const MJsonNode *  params)
static

Definition at line 459 of file mjsonrpc.cxx.

460{
461 if (!params) {
462 MJSO *doc = MJSO::I();
463 doc->D("calls MIDAS cm_shutdown() to stop given MIDAS program");
464 doc->P("name", MJSON_STRING, "name of the program, corresponding to ODB /Programs/name");
465 doc->R("status", MJSON_INT, "return status of cm_shutdown()");
466 return doc;
467 }
468
469 MJsonNode* error = NULL;
470
471 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString();
472 if (error)
473 return error;
474
475 int status = cm_shutdown(name.c_str());
476
477 if (mjsonrpc_debug)
478 printf("cm_shutdown(%s) -> %d\n", name.c_str(), status);
479
480 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
481}
INT cm_shutdown(const char *name, BOOL bUnique)
Definition midas.cxx:7474
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_cm_transition()

static MJsonNode * js_cm_transition ( const MJsonNode *  params)
static

Definition at line 3580 of file mjsonrpc.cxx.

3581{
3582 if (!params) {
3583 MJSO* doc = MJSO::I();
3584 doc->D("start and stop runs");
3585 doc->P("transition", MJSON_STRING, "requested transition: TR_START, TR_STOP, TR_PAUSE, TR_RESUME");
3586 doc->P("run_number?", MJSON_INT, "New run number, value 0 means /runinfo/run_number + 1, default is 0");
3587 doc->P("async_flag?", MJSON_INT, "Transition type. Default is multithreaded transition TR_MTHREAD");
3588 doc->P("debug_flag?", MJSON_INT, "See cm_transition(), value 1: trace to stdout, value 2: trace to midas.log");
3589 doc->R("status", MJSON_INT, "return status of cm_transition()");
3590 doc->R("error_string?", MJSON_STRING, "return error string from cm_transition()");
3591 return doc;
3592 }
3593
3594 MJsonNode* error = NULL;
3595
3596 std::string xtransition = mjsonrpc_get_param(params, "transition", &error)->GetString(); if (error) return error;
3597 int run_number = mjsonrpc_get_param(params, "run_number", NULL)->GetInt();
3598 int async_flag = mjsonrpc_get_param(params, "async_flag", NULL)->GetInt();
3599 int debug_flag = mjsonrpc_get_param(params, "debug_flag", NULL)->GetInt();
3600
3601 int status;
3602
3603 int transition = 0;
3604
3605 if (xtransition == "TR_START")
3607 else if (xtransition == "TR_STOP")
3609 else if (xtransition == "TR_PAUSE")
3611 else if (xtransition == "TR_RESUME")
3613 else {
3614 return mjsonrpc_make_error(15, "invalid value of \"transition\"", xtransition.c_str());
3615 }
3616
3617 if (async_flag == 0)
3618 async_flag = TR_MTHREAD;
3619
3620 char error_str[1024];
3621
3622 status = cm_transition(transition, run_number, error_str, sizeof(error_str), async_flag, debug_flag);
3623
3624 MJsonNode* result = MJsonNode::MakeObject();
3625
3626 result->AddToObject("status", MJsonNode::MakeInt(status));
3627 if (strlen(error_str) > 0) {
3628 ss_repair_utf8(error_str);
3629 result->AddToObject("error_string", MJsonNode::MakeString(error_str));
3630 }
3631 return mjsonrpc_make_result(result);
3632}
INT transition(INT run_number, char *error)
Definition consume.cxx:35
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
Definition midas.cxx:5360
#define TR_RESUME
Definition midas.h:408
#define TR_PAUSE
Definition midas.h:407
#define TR_START
Definition midas.h:405
#define TR_MTHREAD
Definition midas.h:361
#define TR_STOP
Definition midas.h:406
INT run_number[2]
Definition mana.cxx:246
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_copy()

static MJsonNode * js_db_copy ( const MJsonNode *  params)
static

Definition at line 857 of file mjsonrpc.cxx.

858{
859 if (!params) {
860 MJSO* doc = MJSO::I();
861 doc->D("get complete ODB data in the \"save\" json encoding, suitable for reloading with odbedit command \"load\"");
862 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths");
863 doc->R("data[]", MJSON_OBJECT, "keys and values of ODB data for each path");
864 doc->R("status[]", MJSON_INT, "return status of db_copy_json_save() for each path");
865 return doc;
866 }
867
868 MJsonNode* error = NULL;
869
870 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
871
872 MJsonNode* dresult = MJsonNode::MakeArray();
873 MJsonNode* sresult = MJsonNode::MakeArray();
874
875 HNDLE hDB;
877
878 for (unsigned i=0; i<paths->size(); i++) {
879 int status = 0;
880 HNDLE hkey;
881 std::string path = (*paths)[i]->GetString();
882
883 status = db_find_key(hDB, 0, path.c_str(), &hkey);
884 if (status != DB_SUCCESS) {
885 dresult->AddToArray(MJsonNode::MakeNull());
886 sresult->AddToArray(MJsonNode::MakeInt(status));
887 continue;
888 }
889
890 char* buf = NULL;
891 int bufsize = 0;
892 int end = 0;
893
894 status = db_copy_json_save(hDB, hkey, &buf, &bufsize, &end);
895
896 if (status == DB_SUCCESS) {
897 ss_repair_utf8(buf);
898 dresult->AddToArray(MJsonNode::MakeJSON(buf));
899 sresult->AddToArray(MJsonNode::MakeInt(status));
900 } else {
901 dresult->AddToArray(MJsonNode::MakeNull());
902 sresult->AddToArray(MJsonNode::MakeInt(status));
903 }
904
905 if (buf)
906 free(buf);
907 }
908
909 return mjsonrpc_make_result("data", dresult, "status", sresult);
910}
INT db_copy_json_save(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:11057
#define end
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_create()

static MJsonNode * js_db_create ( const MJsonNode *  params)
static

Definition at line 1027 of file mjsonrpc.cxx.

1028{
1029 if (!params) {
1030 MJSO* doc = MJSO::I();
1031 doc->D("Create new ODB entries");
1032 MJSO* o = doc->PA("array of ODB paths to be created")->AddObject("", "arguments to db_create_key() and db_set_num_values()");
1033 o->Add("path", MJSON_STRING, "ODB path to be created");
1034 o->Add("type", MJSON_INT, "MIDAS TID_xxx type");
1035 o->Add("array_length?", MJSON_INT, "optional array length, default is 1");
1036 o->Add("string_length?", MJSON_INT, "for TID_STRING, optional string length, default is NAME_LENGTH");
1037 doc->R("status[]", MJSON_INT, "return status of db_create_key(), db_set_num_values() and db_set_data() (for TID_STRING) for each path");
1038 return doc;
1039 }
1040
1041 MJsonNode* sresult = MJsonNode::MakeArray();
1042
1043 const MJsonNodeVector* pp = params->GetArray();
1044
1045 if (!pp) {
1046 delete sresult;
1047 return mjsonrpc_make_error(-32602, "Invalid params", "parameters must be an array of objects");
1048 }
1049
1050 HNDLE hDB;
1052
1053 for (unsigned i=0; i<pp->size(); i++) {
1054 const MJsonNode* p = (*pp)[i];
1055 std::string path = mjsonrpc_get_param(p, "path", NULL)->GetString();
1056 int type = mjsonrpc_get_param(p, "type", NULL)->GetInt();
1057 int array_length = mjsonrpc_get_param(p, "array_length", NULL)->GetInt();
1058 int string_length = mjsonrpc_get_param(p, "string_length", NULL)->GetInt();
1059
1060 //printf("create odb [%s], type %d, array %d, string %d\n", path.c_str(), type, array_length, string_length);
1061
1062 if (string_length == 0)
1063 string_length = NAME_LENGTH;
1064
1065 int status = db_create_key(hDB, 0, path.c_str(), type);
1066
1067 if (status == DB_SUCCESS && string_length > 0 && type == TID_STRING) {
1068 HNDLE hKey;
1069 status = db_find_key(hDB, 0, path.c_str(), &hKey);
1070 if (status == DB_SUCCESS) {
1071 char* buf = (char*)calloc(1, string_length);
1072 assert(buf != NULL);
1073 int size = string_length;
1074 status = db_set_data(hDB, hKey, buf, size, 1, TID_STRING);
1075 free(buf);
1076 }
1077 }
1078
1079 if (status == DB_SUCCESS && array_length > 1) {
1080 HNDLE hKey;
1081 status = db_find_key(hDB, 0, path.c_str(), &hKey);
1082 if (status == DB_SUCCESS)
1083 status = db_set_num_values(hDB, hKey, array_length);
1084 }
1085
1086 sresult->AddToArray(MJsonNode::MakeInt(status));
1087 }
1088
1089 return mjsonrpc_make_result("status", sresult);
1090}
#define TID_STRING
Definition midas.h:346
MJSO * AddObject(const char *name, const char *description)
Definition mjsonrpc.cxx:385
void Add(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:356
MJSO * PA(const char *description)
Definition mjsonrpc.cxx:326
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3887
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7734
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:8018
#define NAME_LENGTH
Definition midas.h:272
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_delete()

static MJsonNode * js_db_delete ( const MJsonNode *  params)
static

Definition at line 1092 of file mjsonrpc.cxx.

1093{
1094 if (!params) {
1095 MJSO* doc = MJSO::I();
1096 doc->D("delete ODB keys");
1097 doc->P("paths[]", MJSON_STRING, "array of ODB paths to delete");
1098 doc->R("status[]", MJSON_INT, "return status of db_delete() for each path");
1099 return doc;
1100 }
1101
1102 MJsonNode* error = NULL;
1103
1104 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1105
1106 MJsonNode* sresult = MJsonNode::MakeArray();
1107
1108 HNDLE hDB;
1110
1111 for (unsigned i=0; i<paths->size(); i++) {
1112 std::string path = (*paths)[i]->GetString();
1113 int status = db_delete(hDB, 0, path.c_str());
1114 sresult->AddToArray(MJsonNode::MakeInt(status));
1115 }
1116
1117 return mjsonrpc_make_result("status", sresult);
1118}
INT db_delete(HNDLE hDB, HNDLE hKeyRoot, const char *odb_path)
Definition odb.cxx:4494
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_get_values()

static MJsonNode * js_db_get_values ( const MJsonNode *  params)
static

Definition at line 637 of file mjsonrpc.cxx.

638{
639 if (!params) {
640 MJSO* doc = MJSO::I();
641 doc->D("get values of ODB data from given subtrees");
642 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths, see note on array indices");
643 doc->P("omit_names?", MJSON_BOOL, "omit the /name entries");
644 doc->P("omit_last_written?", MJSON_BOOL, "omit the /last_written entries and the last_written[] result");
645 doc->P("omit_tid?", MJSON_BOOL, "omit the tid[] result");
646 doc->P("omit_old_timestamp?", MJSON_NUMBER, "omit data older than given ODB timestamp");
647 doc->P("preserve_case?", MJSON_BOOL, "preserve the capitalization of ODB key names (WARNING: ODB is not case sensitive); note that this will also have side effect of setting the omit_names option");
648 doc->R("data[]", 0, "values of ODB data for each path, all key names are in lower case, all symlinks are followed");
649 doc->R("status[]", MJSON_INT, "return status of db_copy_json_values() or db_copy_json_index() for each path");
650 doc->R("tid?[]", MJSON_INT, "odb type id for each path, absent if omit_tid is true");
651 doc->R("last_written?[]", MJSON_NUMBER, "last_written value of the ODB subtree for each path, absent if omit_last_written is true");
652 return doc;
653 }
654
655 MJsonNode* error = NULL;
656
657 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
658
659 bool omit_names = mjsonrpc_get_param(params, "omit_names", NULL)->GetBool();
660 bool omit_last_written = mjsonrpc_get_param(params, "omit_last_written", NULL)->GetBool();
661 bool omit_tid = mjsonrpc_get_param(params, "omit_tid", NULL)->GetBool();
662 double xomit_old_timestamp = mjsonrpc_get_param(params, "omit_old_timestamp", NULL)->GetDouble();
663 time_t omit_old_timestamp = (time_t)xomit_old_timestamp;
664 bool preserve_case = mjsonrpc_get_param(params, "preserve_case", NULL)->GetBool();
665
666 MJsonNode* dresult = MJsonNode::MakeArray();
667 MJsonNode* sresult = MJsonNode::MakeArray();
668 MJsonNode* tresult = MJsonNode::MakeArray();
669 MJsonNode* lwresult = MJsonNode::MakeArray();
670
671 HNDLE hDB;
673
674 for (unsigned i=0; i<paths->size(); i++) {
675 int status = 0;
676 HNDLE hkey;
677 KEY key;
678 std::string path = (*paths)[i]->GetString();
679
680 status = db_find_key(hDB, 0, path.c_str(), &hkey);
681 if (status != DB_SUCCESS) {
682 dresult->AddToArray(MJsonNode::MakeNull());
683 sresult->AddToArray(MJsonNode::MakeInt(status));
684 tresult->AddToArray(MJsonNode::MakeNull());
685 lwresult->AddToArray(MJsonNode::MakeNull());
686 continue;
687 }
688
689 status = db_get_key(hDB, hkey, &key);
690 if (status != DB_SUCCESS) {
691 dresult->AddToArray(MJsonNode::MakeNull());
692 sresult->AddToArray(MJsonNode::MakeInt(status));
693 tresult->AddToArray(MJsonNode::MakeNull());
694 lwresult->AddToArray(MJsonNode::MakeNull());
695 continue;
696 }
697
698 if (path.find("[") != std::string::npos) {
699 std::vector<unsigned> list;
700 status = parse_array_index_list("js_db_get_values", path.c_str(), &list);
701
702 if (status != SUCCESS) {
703 dresult->AddToArray(MJsonNode::MakeNull());
704 sresult->AddToArray(MJsonNode::MakeInt(status));
705 tresult->AddToArray(MJsonNode::MakeInt(key.type));
706 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
707 continue;
708 }
709
710 if (list.size() > 1) {
711 MJsonNode *ddresult = MJsonNode::MakeArray();
712 MJsonNode *ssresult = MJsonNode::MakeArray();
713
714 for (unsigned i=0; i<list.size(); i++) {
715 char* buf = NULL;
716 int bufsize = 0;
717 int end = 0;
718
719 status = db_copy_json_index(hDB, hkey, list[i], &buf, &bufsize, &end);
720 if (status == DB_SUCCESS) {
721 ss_repair_utf8(buf);
722 ddresult->AddToArray(MJsonNode::MakeJSON(buf));
723 ssresult->AddToArray(MJsonNode::MakeInt(status));
724 } else {
725 ddresult->AddToArray(MJsonNode::MakeNull());
726 ssresult->AddToArray(MJsonNode::MakeInt(status));
727 }
728
729 if (buf)
730 free(buf);
731 }
732
733 dresult->AddToArray(ddresult);
734 sresult->AddToArray(ssresult);
735 tresult->AddToArray(MJsonNode::MakeInt(key.type));
736 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
737
738 } else {
739 char* buf = NULL;
740 int bufsize = 0;
741 int end = 0;
742
743 status = db_copy_json_index(hDB, hkey, list[0], &buf, &bufsize, &end);
744 if (status == DB_SUCCESS) {
745 ss_repair_utf8(buf);
746 dresult->AddToArray(MJsonNode::MakeJSON(buf));
747 sresult->AddToArray(MJsonNode::MakeInt(status));
748 tresult->AddToArray(MJsonNode::MakeInt(key.type));
749 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
750 } else {
751 dresult->AddToArray(MJsonNode::MakeNull());
752 sresult->AddToArray(MJsonNode::MakeInt(status));
753 tresult->AddToArray(MJsonNode::MakeInt(key.type));
754 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
755 }
756
757 if (buf)
758 free(buf);
759 }
760 } else {
761 char* buf = NULL;
762 int bufsize = 0;
763 int end = 0;
764
765 status = db_copy_json_values(hDB, hkey, &buf, &bufsize, &end, omit_names,
766 omit_last_written, omit_old_timestamp, preserve_case);
767
768 if (status == DB_SUCCESS) {
769 ss_repair_utf8(buf);
770 dresult->AddToArray(MJsonNode::MakeJSON(buf));
771 sresult->AddToArray(MJsonNode::MakeInt(status));
772 tresult->AddToArray(MJsonNode::MakeInt(key.type));
773 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
774 } else {
775 dresult->AddToArray(MJsonNode::MakeNull());
776 sresult->AddToArray(MJsonNode::MakeInt(status));
777 tresult->AddToArray(MJsonNode::MakeInt(key.type));
778 lwresult->AddToArray(MJsonNode::MakeInt(key.last_written));
779 }
780
781 if (buf)
782 free(buf);
783 }
784 }
785
786 MJsonNode* result = MJsonNode::MakeObject();
787
788 result->AddToObject("data", dresult);
789 result->AddToObject("status", sresult);
790 if (!omit_tid)
791 result->AddToObject("tid", tresult);
792 else
793 delete tresult;
794 if (!omit_last_written)
795 result->AddToObject("last_written", lwresult);
796 else
797 delete lwresult;
798
799 return mjsonrpc_make_result(result);
800}
INT db_copy_json_index(HNDLE hDB, HNDLE hKey, int index, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:10803
INT db_copy_json_values(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int omit_names, int omit_last_written, time_t omit_old_timestamp, int preserve_case)
Definition odb.cxx:11025
static int parse_array_index_list(const char *method, const char *path, std::vector< unsigned > *list)
Definition mjsonrpc.cxx:557
DWORD type
Definition midas.h:1028
INT last_written
Definition midas.h:1038
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_key()

static MJsonNode * js_db_key ( const MJsonNode *  params)
static

Definition at line 1222 of file mjsonrpc.cxx.

1223{
1224 if (!params) {
1225 MJSO* doc = MJSO::I();
1226 doc->D("get ODB keys");
1227 doc->P("paths[]", MJSON_STRING, "array of ODB paths");
1228 doc->R("status[]", MJSON_INT, "return status of db_key() for each path");
1229 doc->R("keys[]", MJSON_OBJECT, "key data for each path");
1230 doc->R("keys[].type", MJSON_INT, "key type TID_xxx");
1231 doc->R("keys[].num_values", MJSON_INT, "array length, 1 for normal entries");
1232 doc->R("keys[].name", MJSON_STRING, "key name");
1233 doc->R("keys[].total_size", MJSON_INT, "data total size in bytes");
1234 doc->R("keys[].item_size", MJSON_INT, "array element size, string length for TID_STRING");
1235 doc->R("keys[].access_mode", MJSON_INT, "access mode bitmap of MODE_xxx");
1236 doc->R("keys[].notify_count", MJSON_INT, "number of hotlinks attached to this key");
1237 doc->R("keys[].last_written", MJSON_INT, "timestamp when data was last updated");
1238 return doc;
1239 }
1240
1241 MJsonNode* error = NULL;
1242
1243 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1244
1245 MJsonNode* kresult = MJsonNode::MakeArray();
1246 MJsonNode* sresult = MJsonNode::MakeArray();
1247
1248 HNDLE hDB;
1250
1251 for (unsigned i=0; i<paths->size(); i++) {
1252 int status = 0;
1253 HNDLE hkey;
1254 KEY key;
1255 std::string path = (*paths)[i]->GetString();
1256
1257 status = db_find_key(hDB, 0, path.c_str(), &hkey);
1258 if (status != DB_SUCCESS) {
1259 kresult->AddToArray(MJsonNode::MakeNull());
1260 sresult->AddToArray(MJsonNode::MakeInt(status));
1261 continue;
1262 }
1263
1264 status = db_get_key(hDB, hkey, &key);
1265 if (status != DB_SUCCESS) {
1266 kresult->AddToArray(MJsonNode::MakeNull());
1267 sresult->AddToArray(MJsonNode::MakeInt(status));
1268 continue;
1269 }
1270
1271 MJsonNode* jkey = MJsonNode::MakeObject();
1272
1273 jkey->AddToObject("type", MJsonNode::MakeInt(key.type));
1274 jkey->AddToObject("num_values", MJsonNode::MakeInt(key.num_values));
1276 jkey->AddToObject("name", MJsonNode::MakeString(key.name));
1277 jkey->AddToObject("total_size", MJsonNode::MakeInt(key.total_size));
1278 jkey->AddToObject("item_size", MJsonNode::MakeInt(key.item_size));
1279 jkey->AddToObject("access_mode", MJsonNode::MakeInt(key.access_mode));
1280 jkey->AddToObject("notify_count", MJsonNode::MakeInt(key.notify_count));
1281 jkey->AddToObject("last_written", MJsonNode::MakeInt(key.last_written));
1282
1283 kresult->AddToArray(jkey);
1284 sresult->AddToArray(MJsonNode::MakeInt(status));
1285 }
1286
1287 return mjsonrpc_make_result("keys", kresult, "status", sresult);
1288}
INT num_values
Definition midas.h:1029
WORD notify_count
Definition midas.h:1035
INT total_size
Definition midas.h:1032
WORD access_mode
Definition midas.h:1034
INT item_size
Definition midas.h:1033
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_link()

static MJsonNode * js_db_link ( const MJsonNode *  params)
static

Definition at line 1340 of file mjsonrpc.cxx.

1341{
1342 if (!params) {
1343 MJSO* doc = MJSO::I();
1344 doc->D("Create ODB symlinks");
1345 doc->P("new_links[]", MJSON_STRING, "array of new symlinks to be created");
1346 doc->P("target_paths[]", MJSON_STRING, "array of existing ODB paths for each link");
1347 doc->R("status[]", MJSON_INT, "return status of db_create_link() for each path");
1348 return doc;
1349 }
1350
1351 MJsonNode* error = NULL;
1352
1353 const MJsonNodeVector* target_paths = mjsonrpc_get_param_array(params, "target_paths", &error); if (error) return error;
1354 const MJsonNodeVector* new_links = mjsonrpc_get_param_array(params, "new_links", &error); if (error) return error;
1355
1356 if (target_paths->size() != new_links->size()) {
1357 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"target_paths\" and \"new_links\" should have the same length");
1358 }
1359
1360 MJsonNode* sresult = MJsonNode::MakeArray();
1361
1362 HNDLE hDB;
1364
1365 for (unsigned i=0; i<new_links->size(); i++) {
1366 int status = 0;
1367 std::string target_path = (*target_paths)[i]->GetString();
1368 std::string new_link = (*new_links)[i]->GetString();
1369 if (new_link.length() < 1) {
1370 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1371 continue;
1372 }
1373
1374 status = db_create_link(hDB, 0, new_link.c_str(), target_path.c_str());
1375
1376 sresult->AddToArray(MJsonNode::MakeInt(status));
1377 }
1378
1379 return mjsonrpc_make_result("status", sresult);
1380}
#define DB_INVALID_PARAM
Definition midas.h:640
INT db_create_link(HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination)
Definition odb.cxx:4183
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_ls()

static MJsonNode * js_db_ls ( const MJsonNode *  params)
static

Definition at line 802 of file mjsonrpc.cxx.

803{
804 if (!params) {
805 MJSO* doc = MJSO::I();
806 doc->D("get contents of given ODB subdirectory in the \"ls\" json encoding - similar to odbedit command \"ls -l\"");
807 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths");
808 doc->R("data[]", MJSON_OBJECT, "keys and values of ODB data for each path");
809 doc->R("status[]", MJSON_INT, "return status of db_copy_json_ls() for each path");
810 return doc;
811 }
812
813 MJsonNode* error = NULL;
814
815 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
816
817 MJsonNode* dresult = MJsonNode::MakeArray();
818 MJsonNode* sresult = MJsonNode::MakeArray();
819
820 HNDLE hDB;
822
823 for (unsigned i=0; i<paths->size(); i++) {
824 int status = 0;
825 HNDLE hkey;
826 std::string path = (*paths)[i]->GetString();
827
828 status = db_find_key(hDB, 0, path.c_str(), &hkey);
829 if (status != DB_SUCCESS) {
830 dresult->AddToArray(MJsonNode::MakeNull());
831 sresult->AddToArray(MJsonNode::MakeInt(status));
832 continue;
833 }
834
835 char* buf = NULL;
836 int bufsize = 0;
837 int end = 0;
838
839 status = db_copy_json_ls(hDB, hkey, &buf, &bufsize, &end);
840
841 if (status == DB_SUCCESS) {
842 ss_repair_utf8(buf);
843 dresult->AddToArray(MJsonNode::MakeJSON(buf));
844 sresult->AddToArray(MJsonNode::MakeInt(status));
845 } else {
846 dresult->AddToArray(MJsonNode::MakeNull());
847 sresult->AddToArray(MJsonNode::MakeInt(status));
848 }
849
850 if (buf)
851 free(buf);
852 }
853
854 return mjsonrpc_make_result("data", dresult, "status", sresult);
855}
INT db_copy_json_ls(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:11003
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_paste()

static MJsonNode * js_db_paste ( const MJsonNode *  params)
static

Definition at line 912 of file mjsonrpc.cxx.

913{
914 if (!params) {
915 MJSO* doc = MJSO::I();
916 doc->D("write data into ODB");
917 doc->P("paths[]", MJSON_STRING, "array of ODB subtree paths, see note on array indices");
918 doc->P("values[]", 0, "array of data values written to ODB via db_paste_json() for each path");
919 doc->R("status[]", MJSON_INT, "array of return status of db_paste_json() for each path");
920 return doc;
921 }
922
923 MJsonNode* error = NULL;
924
925 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
926 const MJsonNodeVector* values = mjsonrpc_get_param_array(params, "values", &error); if (error) return error;
927
928 if (paths->size() != values->size()) {
929 return mjsonrpc_make_error(-32602, "Invalid params", "paths and values should have the same length");
930 }
931
932 MJsonNode* sresult = MJsonNode::MakeArray();
933
934 HNDLE hDB;
936
937 for (unsigned i=0; i<paths->size(); i++) {
938 int status = 0;
939 HNDLE hkey;
940 std::string path = (*paths)[i]->GetString();
941
942 status = db_find_key(hDB, 0, path.c_str(), &hkey);
943 if (status != DB_SUCCESS) {
944 sresult->AddToArray(MJsonNode::MakeInt(status));
945 continue;
946 }
947
948 const MJsonNode* v = (*values)[i];
949 assert(v != NULL);
950
951 if (path.find("[*]") != std::string::npos) {
952
953 KEY key;
954 db_get_key(hDB, hkey, &key);
955 for (int j=0 ; j<key.num_values ; j++)
956 status = db_paste_json_node(hDB, hkey, j, v);
957
958 } else if (path.find("[") != std::string::npos) {
959 std::vector<unsigned> list;
960 status = parse_array_index_list("js_db_paste", path.c_str(), &list);
961
962 if (status != SUCCESS) {
963 sresult->AddToArray(MJsonNode::MakeInt(status));
964 continue;
965 }
966
967 // supported permutations of array indices and data values:
968 // single index: intarray[1] -> data should be a single value: MJSON_ARRAY is rejected right here, MJSON_OBJECT is rejected by db_paste
969 // multiple index intarray[1,2,3] -> data should be an array of equal length, or
970 // multiple index intarray[1,2,3] -> if data is a single value, all array elements are set to this same value
971
972 if (list.size() < 1) {
973 cm_msg(MERROR, "js_db_paste", "invalid array indices for array path \"%s\"", path.c_str());
974 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
975 continue;
976 } else if (list.size() == 1) {
977 if (v->GetType() == MJSON_ARRAY) {
978 cm_msg(MERROR, "js_db_paste", "unexpected array of values for array path \"%s\"", path.c_str());
979 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
980 continue;
981 }
982
983 status = db_paste_json_node(hDB, hkey, list[0], v);
984 sresult->AddToArray(MJsonNode::MakeInt(status));
985 } else if ((list.size() > 1) && (v->GetType() == MJSON_ARRAY)) {
986 const MJsonNodeVector* vvalues = v->GetArray();
987
988 if (list.size() != vvalues->size()) {
989 cm_msg(MERROR, "js_db_paste", "length of values array %d should be same as number of indices %d for array path \"%s\"", (int)vvalues->size(), (int)list.size(), path.c_str());
990 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
991 continue;
992 }
993
994 MJsonNode *ssresult = MJsonNode::MakeArray();
995
996 for (unsigned j =0; j <list.size(); j++) {
997 const MJsonNode* vv = (*vvalues)[j];
998
999 if (vv == NULL) {
1000 cm_msg(MERROR, "js_db_paste", "internal error: NULL array value at index %d for array path \"%s\"", j, path.c_str());
1001 sresult->AddToArray(MJsonNode::MakeInt(DB_TYPE_MISMATCH));
1002 continue;
1003 }
1004
1005 status = db_paste_json_node(hDB, hkey, list[j], vv);
1006 ssresult->AddToArray(MJsonNode::MakeInt(status));
1007 }
1008
1009 sresult->AddToArray(ssresult);
1010 } else {
1011 MJsonNode *ssresult = MJsonNode::MakeArray();
1012 for (unsigned j =0; j <list.size(); j++) {
1013 status = db_paste_json_node(hDB, hkey, list[j], v);
1014 ssresult->AddToArray(MJsonNode::MakeInt(status));
1015 }
1016 sresult->AddToArray(ssresult);
1017 }
1018 } else {
1019 status = db_paste_json_node(hDB, hkey, 0, v);
1020 sresult->AddToArray(MJsonNode::MakeInt(status));
1021 }
1022 }
1023
1024 return mjsonrpc_make_result("status", sresult);
1025}
#define DB_TYPE_MISMATCH
Definition midas.h:646
INT EXPRT db_paste_json_node(HNDLE hDB, HNDLE hKeyRoot, int index, const MJsonNode *node)
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_rename()

static MJsonNode * js_db_rename ( const MJsonNode *  params)
static

Definition at line 1290 of file mjsonrpc.cxx.

1291{
1292 if (!params) {
1293 MJSO* doc = MJSO::I();
1294 doc->D("Change size of ODB arrays");
1295 doc->P("paths[]", MJSON_STRING, "array of ODB paths to rename");
1296 doc->P("new_names[]", MJSON_STRING, "array of new names for each ODB path");
1297 doc->R("status[]", MJSON_INT, "return status of db_rename_key() for each path");
1298 return doc;
1299 }
1300
1301 MJsonNode* error = NULL;
1302
1303 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1304 const MJsonNodeVector* names = mjsonrpc_get_param_array(params, "new_names", &error); if (error) return error;
1305
1306 if (paths->size() != names->size()) {
1307 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_names\" should have the same length");
1308 }
1309
1310 MJsonNode* sresult = MJsonNode::MakeArray();
1311
1312 HNDLE hDB;
1314
1315 for (unsigned i=0; i<paths->size(); i++) {
1316 int status = 0;
1317 HNDLE hkey;
1318 std::string path = (*paths)[i]->GetString();
1319
1320 status = db_find_link(hDB, 0, path.c_str(), &hkey);
1321 if (status != DB_SUCCESS) {
1322 sresult->AddToArray(MJsonNode::MakeInt(status));
1323 continue;
1324 }
1325
1326 std::string new_name = (*names)[i]->GetString();
1327 if (new_name.length() < 1) {
1328 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1329 continue;
1330 }
1331
1332 status = db_rename_key(hDB, hkey, new_name.c_str());
1333
1334 sresult->AddToArray(MJsonNode::MakeInt(status));
1335 }
1336
1337 return mjsonrpc_make_result("status", sresult);
1338}
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4788
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
Definition odb.cxx:6780
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_reorder()

static MJsonNode * js_db_reorder ( const MJsonNode *  params)
static

Definition at line 1382 of file mjsonrpc.cxx.

1383{
1384 if (!params) {
1385 MJSO* doc = MJSO::I();
1386 doc->D("Change order of ODB keys in a subdirectory");
1387 doc->P("paths[]", MJSON_STRING, "array of new symlinks to be created");
1388 doc->P("indices[]", MJSON_INT, "array of existing ODB paths for each link");
1389 doc->R("status[]", MJSON_INT, "return status of db_reorder_key() for each path");
1390 return doc;
1391 }
1392
1393 MJsonNode* error = NULL;
1394
1395 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1396 const MJsonNodeVector* indices = mjsonrpc_get_param_array(params, "indices", &error); if (error) return error;
1397
1398 if (paths->size() != indices->size()) {
1399 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"indices\" should have the same length");
1400 }
1401
1402 MJsonNode* sresult = MJsonNode::MakeArray();
1403
1404 HNDLE hDB;
1406
1407 for (unsigned i=0; i<paths->size(); i++) {
1408 int status = 0;
1409 HNDLE hkey;
1410 std::string path = (*paths)[i]->GetString();
1411 int index = (*indices)[i]->GetInt();
1412
1413 status = db_find_key(hDB, 0, path.c_str(), &hkey);
1414 if (status != DB_SUCCESS) {
1415 sresult->AddToArray(MJsonNode::MakeInt(status));
1416 continue;
1417 }
1418
1419 status = db_reorder_key(hDB, hkey, index);
1420
1421 sresult->AddToArray(MJsonNode::MakeInt(status));
1422 }
1423
1424 return mjsonrpc_make_result("status", sresult);
1425}
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6880
INT index
Definition mana.cxx:271
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_resize()

static MJsonNode * js_db_resize ( const MJsonNode *  params)
static

Definition at line 1120 of file mjsonrpc.cxx.

1121{
1122 if (!params) {
1123 MJSO* doc = MJSO::I();
1124 doc->D("Change size of ODB arrays");
1125 doc->P("paths[]", MJSON_STRING, "array of ODB paths to resize");
1126 doc->P("new_lengths[]", MJSON_INT, "array of new lengths for each ODB path");
1127 doc->R("status[]", MJSON_INT, "return status of db_set_num_values() for each path");
1128 return doc;
1129 }
1130
1131 MJsonNode* error = NULL;
1132
1133 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1134 const MJsonNodeVector* lengths = mjsonrpc_get_param_array(params, "new_lengths", &error); if (error) return error;
1135
1136 if (paths->size() != lengths->size()) {
1137 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_lengths\" should have the same length");
1138 }
1139
1140 MJsonNode* sresult = MJsonNode::MakeArray();
1141
1142 HNDLE hDB;
1144
1145 for (unsigned i=0; i<paths->size(); i++) {
1146 int status = 0;
1147 HNDLE hkey;
1148 std::string path = (*paths)[i]->GetString();
1149
1150 status = db_find_key(hDB, 0, path.c_str(), &hkey);
1151 if (status != DB_SUCCESS) {
1152 sresult->AddToArray(MJsonNode::MakeInt(status));
1153 continue;
1154 }
1155
1156 int length = (*lengths)[i]->GetInt();
1157 if (length < 1) {
1158 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1159 continue;
1160 }
1161
1162 status = db_set_num_values(hDB, hkey, length);
1163 sresult->AddToArray(MJsonNode::MakeInt(status));
1164 }
1165
1166 return mjsonrpc_make_result("status", sresult);
1167}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_resize_string()

static MJsonNode * js_db_resize_string ( const MJsonNode *  params)
static

Definition at line 1169 of file mjsonrpc.cxx.

1170{
1171 if (!params) {
1172 MJSO* doc = MJSO::I();
1173 doc->D("Change size of ODB string arrays");
1174 doc->P("paths[]", MJSON_STRING, "array of ODB paths to resize");
1175 doc->P("new_lengths[]", MJSON_INT, "array of new lengths for each ODB path");
1176 doc->P("new_string_lengths[]", MJSON_INT, "array of new string lengths for each ODB path");
1177 doc->R("status[]", MJSON_INT, "return status of db_resize_string() for each path");
1178 return doc;
1179 }
1180
1181 MJsonNode* error = NULL;
1182
1183 const MJsonNodeVector* paths = mjsonrpc_get_param_array(params, "paths", &error); if (error) return error;
1184 const MJsonNodeVector* lengths = mjsonrpc_get_param_array(params, "new_lengths", &error); if (error) return error;
1185 const MJsonNodeVector* string_lengths = mjsonrpc_get_param_array(params, "new_string_lengths", &error); if (error) return error;
1186
1187 if (paths->size() != lengths->size()) {
1188 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_lengths\" should have the same length");
1189 }
1190
1191 if (paths->size() != string_lengths->size()) {
1192 return mjsonrpc_make_error(-32602, "Invalid params", "arrays \"paths\" and \"new_string_lengths\" should have the same length");
1193 }
1194
1195 MJsonNode* sresult = MJsonNode::MakeArray();
1196
1197 HNDLE hDB;
1199
1200 for (unsigned i=0; i<paths->size(); i++) {
1201 std::string path = (*paths)[i]->GetString();
1202
1203 int length = (*lengths)[i]->GetInt();
1204 if (length < 0) {
1205 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1206 continue;
1207 }
1208
1209 int string_length = (*string_lengths)[i]->GetInt();
1210 if (length < 0) {
1211 sresult->AddToArray(MJsonNode::MakeInt(DB_INVALID_PARAM));
1212 continue;
1213 }
1214
1215 int status = db_resize_string(hDB, 0, path.c_str(), length, string_length);
1216 sresult->AddToArray(MJsonNode::MakeInt(status));
1217 }
1218
1219 return mjsonrpc_make_result("status", sresult);
1220}
INT EXPRT db_resize_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int num_values, int max_string_length)
Definition odb.cxx:14619
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_scl()

static MJsonNode * js_db_scl ( const MJsonNode *  params)
static

Definition at line 1449 of file mjsonrpc.cxx.

1450{
1451 if (!params) {
1452 MJSO* doc = MJSO::I();
1453 doc->D("Show ODB clients");
1454 doc->R("scl", MJSON_JSON, "return value of db_scl()");
1455 return doc;
1456 }
1457
1458 HNDLE hDB;
1460
1461 MJsonNode* scl = db_scl(hDB);
1462
1463 return mjsonrpc_make_result("scl", scl);
1464}
MJsonNode * db_scl(HNDLE hDB)
Definition odb.cxx:14705
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_db_sor()

static MJsonNode * js_db_sor ( const MJsonNode *  params)
static

Definition at line 1427 of file mjsonrpc.cxx.

1428{
1429 if (!params) {
1430 MJSO* doc = MJSO::I();
1431 doc->D("Show ODB open records starting from given ODB path");
1432 doc->P("path?", MJSON_STRING, "ODB path");
1433 doc->R("sor", MJSON_JSON, "return value of db_sor()");
1434 return doc;
1435 }
1436
1437 MJsonNode* error = NULL;
1438
1439 std::string path = mjsonrpc_get_param(params, "path", NULL)->GetString(); if (error) return error;
1440
1441 HNDLE hDB;
1443
1444 MJsonNode* sor = db_sor(hDB, path.c_str());
1445
1446 return mjsonrpc_make_result("sor", sor);
1447}
MJsonNode * db_sor(HNDLE hDB, const char *root_path)
Definition odb.cxx:14755
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_el_delete()

static MJsonNode * js_el_delete ( const MJsonNode *  params)
static

Definition at line 3322 of file mjsonrpc.cxx.

3323{
3324 if (!params) {
3325 MJSO* doc = MJSO::I();
3326 doc->D("Delete elog message");
3327 doc->P("tag", MJSON_STRING, "tag of message to delete");
3328 doc->R("status", MJSON_INT, "return status of el_delete");
3329 return doc;
3330 }
3331
3332 MJsonNode* error = NULL;
3333 std::string tag = mjsonrpc_get_param(params, "tag", &error)->GetString(); if (error) return error;
3334 int status = el_delete_message(tag.c_str());
3335 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
3336}
INT el_delete_message(const char *tag)
Definition elog.cxx:1018
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_el_query()

static MJsonNode * js_el_query ( const MJsonNode *  params)
static

Definition at line 3047 of file mjsonrpc.cxx.

3048{
3049 if (!params) {
3050 MJSO* doc = MJSO::I();
3051 doc->D("Query elog messages");
3052 doc->P("last_n_hours?", MJSON_INT, "return messages from the last N hours");
3053 doc->R("status", MJSON_INT, "return status of el_retrieve");
3054 doc->R("msg[].tag", MJSON_STRING, "message tag");
3055 return doc;
3056 }
3057
3058 //MJsonNode* error = NULL;
3059
3060 //int last_n = mjsonrpc_get_param(params, "last_n_hours", &error)->GetInt(); if (error) return error;
3061 int last_n = mjsonrpc_get_param(params, "last_n_hours", NULL)->GetInt();
3062
3063 std::string pd1 = mjsonrpc_get_param(params, "d1", NULL)->GetString();
3064 std::string pm1 = mjsonrpc_get_param(params, "m1", NULL)->GetString();
3065 std::string py1 = mjsonrpc_get_param(params, "y1", NULL)->GetString();
3066
3067 std::string pd2 = mjsonrpc_get_param(params, "d2", NULL)->GetString();
3068 std::string pm2 = mjsonrpc_get_param(params, "m2", NULL)->GetString();
3069 std::string py2 = mjsonrpc_get_param(params, "y2", NULL)->GetString();
3070
3071 std::string pr1 = mjsonrpc_get_param(params, "r1", NULL)->GetString();
3072 std::string pr2 = mjsonrpc_get_param(params, "r2", NULL)->GetString();
3073
3074 std::string ptype = mjsonrpc_get_param(params, "type", NULL)->GetString();
3075 std::string psystem = mjsonrpc_get_param(params, "system", NULL)->GetString();
3076 std::string pauthor = mjsonrpc_get_param(params, "author", NULL)->GetString();
3077 std::string psubject = mjsonrpc_get_param(params, "subject", NULL)->GetString();
3078 std::string psubtext = mjsonrpc_get_param(params, "subtext", NULL)->GetString();
3079
3080 MJsonNode* msg_array = MJsonNode::MakeArray();
3081
3082 int i, size, run, status;
3083 char date[80], author[80], type[80], system[80], subject[256], text[10000],
3084 orig_tag[80], reply_tag[80], attachment[3][256], encoding[80];
3085 char str[256], str2[10000], tag[256];
3086 struct tm tms;
3087
3088 // month name from midas.c
3089 extern const char *mname[];
3090
3091 /*---- convert end date to ltime ----*/
3092
3093 int y1 = -1;
3094 int m1 = -1;
3095 int d1 = -1;
3096
3097 int y2 = -1;
3098 int m2 = -1;
3099 int d2 = -1;
3100
3101 int r1 = -1;
3102 int r2 = -1;
3103
3104 if (pr1.length()>0)
3105 r1 = atoi(pr1.c_str());
3106
3107 if (pr2.length()>0)
3108 r2 = atoi(pr2.c_str());
3109
3110 time_t ltime_start = 0;
3111 time_t ltime_end = 0;
3112
3113 if (!last_n) {
3114 // decode starting date year, day and month
3115
3116 if (py1.length() > 0)
3117 y1 = atoi(py1.c_str());
3118
3119 if (pd1.length() > 0)
3120 d1 = atoi(pd1.c_str());
3121
3122 mstrlcpy(str, pm1.c_str(), sizeof(str));
3123 for (m1 = 0; m1 < 12; m1++)
3124 if (equal_ustring(str, mname[m1]))
3125 break;
3126 if (m1 == 12)
3127 m1 = 0;
3128
3129 if (pd2.length() > 0) {
3130 d2 = atoi(pd2.c_str());
3131 }
3132
3133 if (py2.length() > 0) {
3134 // decode ending date year, day and month
3135
3136 mstrlcpy(str, pm2.c_str(), sizeof(str));
3137 for (m2 = 0; m2 < 12; m2++)
3138 if (equal_ustring(str, mname[m2]))
3139 break;
3140 if (m2 == 12) {
3141 m2 = 0;
3142 }
3143 }
3144
3145 if (py2.length() > 0) {
3146 y2 = atoi(py2.c_str());
3147 }
3148
3149 if (y2>=0 && m2>=0 && d2>=0) {
3150 memset(&tms, 0, sizeof(struct tm));
3151 tms.tm_year = y2 % 100;
3152 tms.tm_mon = m2;
3153 tms.tm_mday = d2;
3154 tms.tm_hour = 24;
3155
3156 if (tms.tm_year < 90)
3157 tms.tm_year += 100;
3158 ltime_end = ss_mktime(&tms);
3159 }
3160 }
3161
3162 /*---- do query ----*/
3163
3164 tag[0] = 0;
3165
3166 if (last_n) {
3167 ss_tzset(); // required for localtime_r()
3168 time_t now = time(NULL);
3169 ltime_start = now - 3600 * last_n;
3170 struct tm tms;
3171 localtime_r(&ltime_start, &tms);
3172 sprintf(tag, "%02d%02d%02d.0", tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday);
3173 } else if (r1 > 0) {
3174 /* do run query */
3175 el_search_run(r1, tag);
3176 } else if (y1>=0 && m1>=0 && d1>=0) {
3177 /* do date-date query */
3178 sprintf(tag, "%02d%02d%02d.0", y1 % 100, m1 + 1, d1);
3179 }
3180
3181#if 0
3182 printf("js_el_query: y1 %d, m1 %d, d1 %d, y2 %d, m2 %d, d2 %d, r1 %d, r2 %d, last_n_hours %d, start time %lu, end time %lu, tag [%s]\n",
3183 y1, m1, d1,
3184 y2, m2, d2,
3185 r1, r2,
3186 last_n,
3187 ltime_start,
3188 ltime_end,
3189 tag);
3190#endif
3191
3192 do {
3193 size = sizeof(text);
3194 status = el_retrieve(tag, date, &run, author, type, system, subject,
3195 text, &size, orig_tag, reply_tag,
3196 attachment[0], attachment[1], attachment[2], encoding);
3197
3198 std::string this_tag = tag;
3199
3200 //printf("js_el_query: el_retrieve: size %d, status %d, tag [%s], run %d, tags [%s] [%s]\n", size, status, tag, run, orig_tag, reply_tag);
3201
3202 mstrlcat(tag, "+1", sizeof(tag));
3203
3204 /* check for end run */
3205 if ((r2 > 0) && (r2 < run)) {
3206 break;
3207 }
3208
3209 /* convert date to unix format */
3210 memset(&tms, 0, sizeof(struct tm));
3211 tms.tm_year = (tag[0] - '0') * 10 + (tag[1] - '0');
3212 tms.tm_mon = (tag[2] - '0') * 10 + (tag[3] - '0') - 1;
3213 tms.tm_mday = (tag[4] - '0') * 10 + (tag[5] - '0');
3214 tms.tm_hour = (date[11] - '0') * 10 + (date[12] - '0');
3215 tms.tm_min = (date[14] - '0') * 10 + (date[15] - '0');
3216 tms.tm_sec = (date[17] - '0') * 10 + (date[18] - '0');
3217
3218 if (tms.tm_year < 90)
3219 tms.tm_year += 100;
3220
3221 time_t ltime_current = ss_mktime(&tms);
3222
3223 //printf("js_el_query: ltime: start %ld, end %ld, current %ld\n", ltime_start, ltime_end, ltime_current);
3224
3225 /* check for start date */
3226 if (ltime_start > 0)
3227 if (ltime_current < ltime_start)
3228 continue;
3229
3230 /* check for end date */
3231 if (ltime_end > 0) {
3232 if (ltime_current > ltime_end)
3233 break;
3234 }
3235
3236 if (status == EL_SUCCESS) {
3237 /* do filtering */
3238 if ((ptype.length()>0) && !equal_ustring(ptype.c_str(), type))
3239 continue;
3240 if ((psystem.length()>0) && !equal_ustring(psystem.c_str(), system))
3241 continue;
3242
3243 if (pauthor.length()>0) {
3244 mstrlcpy(str, pauthor.c_str(), sizeof(str));
3245 for (i = 0; i < (int) strlen(str); i++)
3246 str[i] = toupper(str[i]);
3247 str[i] = 0;
3248 for (i = 0; i < (int) strlen(author) && author[i] != '@'; i++)
3249 str2[i] = toupper(author[i]);
3250 str2[i] = 0;
3251
3252 if (strstr(str2, str) == NULL)
3253 continue;
3254 }
3255
3256 if (psubject.length()>0) {
3257 mstrlcpy(str, psubject.c_str(), sizeof(str));
3258 for (i = 0; i < (int) strlen(str); i++)
3259 str[i] = toupper(str[i]);
3260 str[i] = 0;
3261 for (i = 0; i < (int) strlen(subject); i++)
3262 str2[i] = toupper(subject[i]);
3263 str2[i] = 0;
3264
3265 if (strstr(str2, str) == NULL)
3266 continue;
3267 }
3268
3269 if (psubtext.length()>0) {
3270 mstrlcpy(str, psubtext.c_str(), sizeof(str));
3271 for (i = 0; i < (int) strlen(str); i++)
3272 str[i] = toupper(str[i]);
3273 str[i] = 0;
3274 for (i = 0; i < (int) strlen(text); i++)
3275 str2[i] = toupper(text[i]);
3276 str2[i] = 0;
3277
3278 if (strstr(str2, str) == NULL)
3279 continue;
3280 }
3281
3282 /* filter passed: display line */
3283
3284 MJsonNode* msg = MJsonNode::MakeObject();
3285
3286 ss_repair_utf8(this_tag);
3287 msg->AddToObject("tag", MJsonNode::MakeString(this_tag.c_str()));
3288 ss_repair_utf8(date);
3289 msg->AddToObject("date", MJsonNode::MakeString(date));
3290 msg->AddToObject("run", MJsonNode::MakeInt(run));
3291 ss_repair_utf8(author);
3292 msg->AddToObject("author", MJsonNode::MakeString(author));
3294 msg->AddToObject("type", MJsonNode::MakeString(type));
3295 ss_repair_utf8(system);
3296 msg->AddToObject("system", MJsonNode::MakeString(system));
3297 ss_repair_utf8(subject);
3298 msg->AddToObject("subject", MJsonNode::MakeString(subject));
3299 ss_repair_utf8(text);
3300 msg->AddToObject("text", MJsonNode::MakeString(text));
3301 ss_repair_utf8(orig_tag);
3302 msg->AddToObject("orig_tag", MJsonNode::MakeString(orig_tag));
3303 ss_repair_utf8(reply_tag);
3304 msg->AddToObject("reply_tag", MJsonNode::MakeString(reply_tag));
3305 ss_repair_utf8(attachment[0]);
3306 msg->AddToObject("attachment0", MJsonNode::MakeString(attachment[0]));
3307 ss_repair_utf8(attachment[1]);
3308 msg->AddToObject("attachment1", MJsonNode::MakeString(attachment[1]));
3309 ss_repair_utf8(attachment[2]);
3310 msg->AddToObject("attachment2", MJsonNode::MakeString(attachment[2]));
3311 ss_repair_utf8(encoding);
3312 msg->AddToObject("encoding", MJsonNode::MakeString(encoding));
3313
3314 msg_array->AddToArray(msg);
3315 }
3316
3317 } while (status == EL_SUCCESS);
3318
3319 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "msg", msg_array);
3320}
INT el_search_run(int run, char *return_tag)
Definition elog.cxx:954
INT el_retrieve(char *tag, char *date, int *run, char *author, char *type, char *syst, char *subject, char *text, int *textsize, char *orig_tag, char *reply_tag, char *attachment1, char *attachment2, char *attachment3, char *encoding)
Definition elog.cxx:774
#define EL_SUCCESS
Definition midas.h:746
time_t ss_mktime(struct tm *tms)
Definition system.cxx:3444
void ss_tzset()
Definition system.cxx:3434
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3780
const char * mname[]
Definition midas.cxx:144
MUTEX_T * tm
Definition odbedit.cxx:39
DWORD run
Definition odbhist.cxx:39
char str[256]
Definition odbhist.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_el_retrieve()

static MJsonNode * js_el_retrieve ( const MJsonNode *  params)
static

Definition at line 2981 of file mjsonrpc.cxx.

2982{
2983 if (!params) {
2984 MJSO* doc = MJSO::I();
2985 doc->D("Get an elog message");
2986 doc->P("tag", MJSON_STRING, "elog message tag");
2987 doc->R("status", MJSON_INT, "return status of el_retrieve");
2988 doc->R("msg.tag", MJSON_STRING, "message tag");
2989 return doc;
2990 }
2991
2992 MJsonNode* error = NULL;
2993
2994 std::string tag = mjsonrpc_get_param(params, "tag", &error)->GetString(); if (error) return error;
2995
2996 int run = 0;
2997 char date[80], author[80], type[80], system[80], subject[256], text[10000];
2998 char orig_tag[80], reply_tag[80], attachment[3][256], encoding[80];
2999
3000 char xtag[80];
3001 mstrlcpy(xtag, tag.c_str(), sizeof(xtag));
3002
3003 int size = sizeof(text);
3004
3005 int status = el_retrieve(xtag,
3006 date, &run, author, type, system, subject,
3007 text, &size, orig_tag, reply_tag,
3008 attachment[0], attachment[1], attachment[2], encoding);
3009
3010 //printf("js_el_retrieve: size %d, status %d, tag [%s]\n", size, status, xtag);
3011
3012 MJsonNode* msg = MJsonNode::MakeObject();
3013
3014 if (status == EL_SUCCESS) {
3015 ss_repair_utf8(xtag);
3016 msg->AddToObject("tag", MJsonNode::MakeString(xtag));
3017 ss_repair_utf8(date);
3018 msg->AddToObject("date", MJsonNode::MakeString(date));
3019 msg->AddToObject("run", MJsonNode::MakeInt(run));
3020 ss_repair_utf8(author);
3021 msg->AddToObject("author", MJsonNode::MakeString(author));
3023 msg->AddToObject("type", MJsonNode::MakeString(type));
3024 ss_repair_utf8(system);
3025 msg->AddToObject("system", MJsonNode::MakeString(system));
3026 ss_repair_utf8(subject);
3027 msg->AddToObject("subject", MJsonNode::MakeString(subject));
3028 ss_repair_utf8(text);
3029 msg->AddToObject("text", MJsonNode::MakeString(text));
3030 ss_repair_utf8(orig_tag);
3031 msg->AddToObject("orig_tag", MJsonNode::MakeString(orig_tag));
3032 ss_repair_utf8(reply_tag);
3033 msg->AddToObject("reply_tag", MJsonNode::MakeString(reply_tag));
3034 ss_repair_utf8(attachment[0]);
3035 msg->AddToObject("attachment0", MJsonNode::MakeString(attachment[0]));
3036 ss_repair_utf8(attachment[1]);
3037 msg->AddToObject("attachment1", MJsonNode::MakeString(attachment[1]));
3038 ss_repair_utf8(attachment[2]);
3039 msg->AddToObject("attachment2", MJsonNode::MakeString(attachment[2]));
3040 ss_repair_utf8(encoding);
3041 msg->AddToObject("encoding", MJsonNode::MakeString(encoding));
3042 }
3043
3044 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "msg", msg);
3045}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ext_list_files()

static MJsonNode * js_ext_list_files ( const MJsonNode *  params)
static

Definition at line 4234 of file mjsonrpc.cxx.

4235{
4236 if (!params) {
4237 MJSO* doc = MJSO::I();
4238 doc->D("js_ext_list_files");
4239 doc->P("subdir", MJSON_STRING, "List files in experiment_directory/userfiles/subdir");
4240 doc->P("fileext", MJSON_STRING, "Filename extension");
4241 doc->R("status", MJSON_INT, "return status of midas library calls");
4242 doc->R("path", MJSON_STRING, "Search path");
4243 doc->R("subdirs[]", MJSON_STRING, "list of subdirectories");
4244 doc->R("files[].filename", MJSON_STRING, "script filename");
4245 doc->R("files[].description", MJSON_STRING, "script description");
4246 return doc;
4247 }
4248
4249 MJsonNode* error = NULL;
4250 std::string subdir = mjsonrpc_get_param(params, "subdir", &error)->GetString(); if (error) return error;
4251 std::string fileext = mjsonrpc_get_param(params, "fileext", &error)->GetString(); if (error) return error;
4252
4253 /*---- Not allowed to contain ../ - safety feature ----*/
4254 if (subdir.find("..") != std::string::npos) {
4255 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The subdir is not permitted"));
4256 }
4257
4258 /*---- ext must start with *. and some not allowed ext - safety feature */
4259 if (fileext.find("..") != std::string::npos) {
4260 /*
4261 fileext.find("/") != std::string::npos ||
4262 fileext.find("*.") != 0 ||
4263 fileext.find("*.html") != std::string::npos || fileext.find("*.HTML") != std::string::npos ||
4264 fileext.find("*.htm") != std::string::npos || fileext.find("*.HTM") != std::string::npos ||
4265 fileext.find("*.js") != std::string::npos || fileext.find("*.JS") != std::string::npos ||
4266 fileext.find("*.pl") != std::string::npos || fileext.find("*.PL") != std::string::npos ||
4267 fileext.find("*.cgi") != std::string::npos || fileext.find("*.CGI") != std::string::npos ||
4268 fileext.find("*.*") != std::string::npos
4269 ) {
4270 */
4271 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename extension is not permitted"));
4272 }
4273
4274 int status;
4275 HNDLE hDB;
4276
4278
4279 if (status != DB_SUCCESS) {
4280 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
4281 }
4282
4283 std::string path = cm_expand_env(cm_get_path().c_str());
4284 if (path[path.length()-1] != DIR_SEPARATOR) {
4285 path += DIR_SEPARATOR_STR;
4286 }
4287 path += "userfiles";
4288
4289 // Check if the userfiles folder exists
4290 if (access(path.c_str(), F_OK) != 0) {
4291 // Create the path if it doesn't exist
4292 if (mkdir(path.c_str(), 0777) != 0) {
4293 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4294 }
4295 }
4296
4297 if (subdir.length() > 0) {
4298 if (subdir[0] != DIR_SEPARATOR) {
4299 path += DIR_SEPARATOR_STR;
4300 }
4301 path += subdir;
4302 }
4303
4304 char* flist = NULL;
4305 MJsonNode* s = MJsonNode::MakeArray();
4306
4307 /*---- go over subdirectories ----*/
4308 int n = ss_dirlink_find(path.c_str(), "*", &flist);
4309
4310 for (int i=0 ; i<n ; i++) {
4311 if (flist[i*MAX_STRING_LENGTH] != '.') {
4312 //printf("subdir %d: [%s]\n", i, flist+i*MAX_STRING_LENGTH);
4314 s->AddToArray(MJsonNode::MakeString(flist+i*MAX_STRING_LENGTH));
4315 }
4316 }
4317
4318 MJsonNode* f = MJsonNode::MakeArray();
4319 time_t modtime = time(NULL);
4320 double fsize;
4321 /*---- go over files with extension fileext in path ----*/
4322 n = ss_file_find(path.c_str(), fileext.c_str(), &flist);
4323
4324 if (n == -1) {
4325 // path does not exist, return an error
4326 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Subdirectory does not exist, create it first."));
4327 }
4328
4329 for (int i=0 ; i<n ; i++) {
4330 //printf("file %d: [%s]\n", i, flist+i*MAX_STRING_LENGTH);
4331 MJsonNode* o = MJsonNode::MakeObject();
4333 o->AddToObject("filename", MJsonNode::MakeString(flist+i*MAX_STRING_LENGTH));
4334 /* description is msl specific, do we need it? */
4335 std::string full_name = path;
4336 if (full_name.back() != DIR_SEPARATOR)
4337 full_name += DIR_SEPARATOR;
4338 full_name.append(flist+i*MAX_STRING_LENGTH);
4339 // o->AddToObject("description", MJsonNode::MakeString(full_name.c_str()));
4340 o->AddToObject("description", MJsonNode::MakeString("description"));
4341 modtime = ss_file_time(full_name.c_str());
4342 o->AddToObject("modtime", MJsonNode::MakeInt(modtime));
4343 fsize = ss_file_size(full_name.c_str());
4344 o->AddToObject("size", MJsonNode::MakeInt(fsize));
4345 f->AddToArray(o);
4346 }
4347
4348 free(flist);
4349 flist = NULL;
4350
4351 MJsonNode* r = MJsonNode::MakeObject();
4352 r->AddToObject("status", MJsonNode::MakeInt(SUCCESS));
4353 ss_repair_utf8(path);
4354 r->AddToObject("path", MJsonNode::MakeString(path.c_str()));
4355 r->AddToObject("subdirs", s);
4356 r->AddToObject("files", f);
4357
4358 return mjsonrpc_make_result(r);
4359
4360}
std::string cm_expand_env(const char *str)
Definition midas.cxx:7823
std::string cm_get_path()
Definition midas.cxx:1587
#define MAX_STRING_LENGTH
Definition msystem.h:113
INT ss_dirlink_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6957
time_t ss_file_time(const char *path)
Definition system.cxx:7095
double ss_file_size(const char *path)
Definition system.cxx:7057
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6798
DWORD n[4]
Definition mana.cxx:247
#define DIR_SEPARATOR
Definition midas.h:193
#define DIR_SEPARATOR_STR
Definition midas.h:194
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ext_read_file()

static MJsonNode * js_ext_read_file ( const MJsonNode *  params)
static

Definition at line 4438 of file mjsonrpc.cxx.

4439{
4440 if (!params) {
4441 MJSO* doc = MJSO::I();
4442 doc->D("js_ext_read_script");
4443 doc->P("filename", MJSON_STRING, "File name, read from experiment_directory/userfiles/filename");
4444 doc->R("content", MJSON_STRING, "ASCII file content");
4445 doc->R("status", MJSON_INT, "return status of midas library calls");
4446 doc->R("error", MJSON_STRING, "error text");
4447 return doc;
4448 }
4449
4450 MJsonNode* error = NULL;
4451 std::string filename = mjsonrpc_get_param(params, "filename", &error)->GetString(); if (error) return error;
4452
4453 /*---- filename should not contain the following - safety feature */
4454 if (filename.find("..") != std::string::npos ||
4455 filename.find("*") != std::string::npos) {
4456 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename is not permitted"));
4457 }
4458
4459 int status;
4460 HNDLE hDB;
4461
4463
4464 if (status != DB_SUCCESS) {
4465 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString("cm_get_experiment_database() error"));
4466 }
4467
4468 std::string path = cm_expand_env(cm_get_path().c_str());
4469 if (path[path.length()-1] != DIR_SEPARATOR) {
4470 path += DIR_SEPARATOR_STR;
4471 }
4472 path += "userfiles";
4473
4474 // Check if the userfiles folder exists
4475 if (access(path.c_str(), F_OK) != 0) {
4476 // Create the path if it doesn't exist
4477 if (mkdir(path.c_str(), 0777) != 0) {
4478 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4479 }
4480 }
4481
4482 path += DIR_SEPARATOR_STR;
4483 path += filename;
4484
4485 FILE* fp = fopen(path.c_str(), "r");
4486 if (!fp) {
4488 char errstr[256];
4489 sprintf(errstr, "fopen() errno %d (%s)", errno, strerror(errno));
4490 ss_repair_utf8(errstr);
4491 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr));
4492 }
4493
4494 fseek(fp, 0, SEEK_END);
4495 size_t file_size = ftell(fp);
4496 rewind(fp);
4497
4498 char* buffer = new char[file_size+1];
4499 fread(buffer, file_size, 1, fp);
4500 // Maybe not needed here
4501 buffer[file_size] = '\0';
4502 fclose(fp);
4503
4504 std::string content = buffer;
4505 delete[] buffer;
4506 buffer = NULL;
4507
4509 std::string errstr = "no error";
4510
4511 return mjsonrpc_make_result("content", MJsonNode::MakeString(content.c_str()), "status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr.c_str()));
4512}
#define CM_SUCCESS
Definition midas.h:582
#define SS_FILE_ERROR
Definition midas.h:670
char content[600000]
Definition melog.cxx:90
static FILE * fp
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ext_save_file()

static MJsonNode * js_ext_save_file ( const MJsonNode *  params)
static

Definition at line 4362 of file mjsonrpc.cxx.

4363{
4364 if (!params) {
4365 MJSO* doc = MJSO::I();
4366 doc->D("js_ext_save_file");
4367 doc->P("filename", MJSON_STRING, "File name, save in experiment_directory/userfiles/filename");
4368 doc->P("script", MJSON_STRING, "ASCII content");
4369 doc->R("status", MJSON_INT, "return status of midas library calls");
4370 doc->R("error", MJSON_STRING, "error text");
4371 return doc;
4372 }
4373
4374 /* Need to make sure that content cannot be abused (e.g. not Javascript code), how?? */
4375
4376 MJsonNode* error = NULL;
4377 std::string filename = mjsonrpc_get_param(params, "filename", &error)->GetString(); if (error) return error;
4378 std::string script = mjsonrpc_get_param(params, "script", &error)->GetString(); if (error) return error;
4379
4380 /*---- filename should not contain the following - safety feature */
4381 if (filename.find("..") != std::string::npos ) {
4382 /*
4383 filename.find("*") != std::string::npos ||
4384 filename.find(".html") != std::string::npos || filename.find(".HTML") != std::string::npos ||
4385 filename.find(".htm") != std::string::npos || filename.find(".HTM") != std::string::npos ||
4386 filename.find(".js") != std::string::npos || filename.find(".JS") != std::string::npos ||
4387 filename.find(".pl") != std::string::npos || filename.find(".PL") != std::string::npos ||
4388 filename.find(".cgi") != std::string::npos || filename.find(".CGI") != std::string::npos
4389 ) {
4390 */
4391 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename is not permitted"));
4392 }
4393
4394 int status;
4395 HNDLE hDB;
4396
4398
4399 if (status != DB_SUCCESS) {
4400 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString("cm_get_experiment_database() error"));
4401 }
4402
4403 std::string path = cm_expand_env(cm_get_path().c_str());
4404 path += "userfiles";
4405
4406 // Check if the userfiles folder exists
4407 if (access(path.c_str(), F_OK) != 0) {
4408 // Create the path if it doesn't exist
4409 if (mkdir(path.c_str(), 0777) != 0) {
4410 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4411 }
4412 }
4413
4414 path += DIR_SEPARATOR_STR;
4415 path += filename;
4416
4417 FILE* fp = fopen(path.c_str(), "w");
4418 if (!fp) {
4420 char errstr[256];
4421 sprintf(errstr, "fopen() errno %d (%s)", errno, strerror(errno));
4422 ss_repair_utf8(errstr);
4423 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr));
4424 }
4425
4426 fwrite(script.c_str(), script.length(), 1, fp);
4427 //fprintf(fp, "\n");
4428 fclose(fp);
4429 fp = NULL;
4430
4432 std::string errstr = "no error";
4433
4434 //ss_repair_utf8(errstr); redundant!
4435 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr.c_str()));
4436}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_get_timezone()

static MJsonNode * js_get_timezone ( const MJsonNode *  params)
static

Definition at line 4694 of file mjsonrpc.cxx.

4695{
4696 if (!params) {
4697 MJSO *doc = MJSO::I();
4698 doc->D("get current server timezone offset in seconds");
4699 doc->P(NULL, 0, "there are no input parameters");
4700 doc->R(NULL, MJSON_INT, "offset in seconds");
4701 return doc;
4702 }
4703
4704 ss_tzset(); // required for localtime_r()
4705 time_t rawtime = time(NULL);
4706 struct tm gmt_tms;
4707 gmtime_r(&rawtime, &gmt_tms);
4708 time_t gmt = ss_mktime(&gmt_tms);
4709 struct tm tms;
4710 localtime_r(&rawtime, &tms);
4711 time_t offset = rawtime - gmt + (tms.tm_isdst ? 3600 : 0);
4712
4713 return mjsonrpc_make_result(MJsonNode::MakeNumber(offset));
4714}
static int offset
Definition mgd.cxx:1500
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_exit()

static void js_hs_exit ( )
static

Definition at line 1736 of file mjsonrpc.cxx.

1737{
1738 for (auto& e : gHistoryChannels) {
1739 //printf("history channel \"%s\" mh %p\n", e.first.c_str(), e.second);
1740 delete e.second;
1741 }
1742 gHistoryChannels.clear();
1743}
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_active_events()

static MJsonNode * js_hs_get_active_events ( const MJsonNode *  params)
static

Definition at line 1658 of file mjsonrpc.cxx.

1659{
1660 if (!params) {
1661 MJSO* doc = MJSO::I();
1662 doc->D("get list of active history events using hs_read_event_list()");
1663 doc->R("status", MJSON_INT, "return status of hs_read_event_list()");
1664 doc->R("events[]", MJSON_STRING, "array of history event names");
1665 return doc;
1666 }
1667
1669
1671
1672 MJsonNode* events = MJsonNode::MakeArray();
1673
1674 for (unsigned i=0; i<list.size(); i++) {
1676 events->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1677 }
1678
1679 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1680}
int hs_read_event_list(std::vector< std::string > *pevents)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_channels()

static MJsonNode * js_hs_get_channels ( const MJsonNode *  params)
static

Definition at line 1745 of file mjsonrpc.cxx.

1746{
1747 if (!params) {
1748 MJSO* doc = MJSO::I();
1749 doc->D("get list of history channels in /Logger/History");
1750 doc->R("status", MJSON_INT, "return success or failure status");
1751 doc->R("default_channel", MJSON_STRING, "name of the default logger history channel");
1752 doc->R("channels[]", MJSON_STRING, "all logger history channel names");
1753 doc->R("active_channels[]", MJSON_STRING, "active logger history channel names");
1754 return doc;
1755 }
1756
1757 MJsonNode* channels = MJsonNode::MakeArray();
1758 MJsonNode* active_channels = MJsonNode::MakeArray();
1759
1760 HNDLE hDB;
1762
1763 // get history channel name selected by user in ODB
1764
1765 //std::string selected_channel;
1766 //db_get_value_string(hDB, 0, "/History/LoggerHistoryChannel", 0, &selected_channel, TRUE);
1767
1768 int status;
1769 HNDLE hKeyChan;
1770
1771 status = db_find_key(hDB, 0, "/Logger/History", &hKeyChan);
1772 if (status == DB_SUCCESS) {
1773 for (int ichan=0; ; ichan++) {
1774 HNDLE hKey;
1775 status = db_enum_key(hDB, hKeyChan, ichan, &hKey);
1776 if (status == DB_NO_MORE_SUBKEYS) {
1778 break;
1779 }
1780 if (status != DB_SUCCESS)
1781 break;
1782
1783 KEY key;
1784
1786
1787 if (status == DB_SUCCESS) {
1789 channels->AddToArray(MJsonNode::MakeString(key.name));
1790
1791 INT active = 0;
1792 INT size = sizeof(active);
1793 status = db_get_value(hDB, hKey, "Active", &active, &size, TID_BOOL, FALSE);
1794 if (status == DB_SUCCESS) {
1795 if (active) {
1796 active_channels->AddToArray(MJsonNode::MakeString(key.name));
1797 }
1798 }
1799 }
1800 }
1801 }
1802
1803 std::string default_channel;
1804
1805 HNDLE hKey;
1807 if (status == DB_SUCCESS) {
1808 KEY key;
1810 if (status == DB_SUCCESS) {
1811 default_channel = key.name;
1812 }
1813 }
1814
1815 return mjsonrpc_make_result("status", MJsonNode::MakeInt(1),
1816 //"selected_channel", MJsonNode::MakeString(selected_channel.c_str()),
1817 "default_channel", MJsonNode::MakeString(default_channel.c_str()),
1818 "active_channels", active_channels,
1819 "channels", channels);
1820}
#define DB_NO_MORE_SUBKEYS
Definition midas.h:647
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5852
int INT
Definition midas.h:129
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_events()

static MJsonNode * js_hs_get_events ( const MJsonNode *  params)
static

Definition at line 1822 of file mjsonrpc.cxx.

1823{
1824 if (!params) {
1825 MJSO* doc = MJSO::I();
1826 doc->D("get list of history events that existed at give time using hs_get_events()");
1827 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1828 doc->P("time?", MJSON_NUMBER, "timestamp, value 0 means current time, default is 0");
1829 doc->R("status", MJSON_INT, "return status of hs_get_events()");
1830 doc->R("channel", MJSON_STRING, "logger history channel name");
1831 doc->R("events[]", MJSON_STRING, "array of history event names");
1832 return doc;
1833 }
1834
1835 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1836 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1837
1839
1840 MJsonNode* events = MJsonNode::MakeArray();
1841
1842 if (!mh) {
1843 int status = HS_FILE_ERROR;
1844 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1845 }
1846
1847 if (time == 0) {
1848 time = ::time(NULL);
1849 }
1850
1852
1853 int status = mh->hs_get_events(time, &list);
1854
1855 for (unsigned i=0; i<list.size(); i++) {
1857 events->AddToArray(MJsonNode::MakeString(list[i].c_str()));
1858 }
1859
1860 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "events", events);
1861}
virtual int hs_get_events(time_t time_from, std::vector< std::string > *pevents)=0
get list of events that exist(ed) at given time and later (value 0 means "return all events from begi...
char name[NAME_LENGTH]
Definition history.h:111
#define HS_FILE_ERROR
Definition midas.h:729
INT channel
static MidasHistoryInterface * GetHistory(const char *name)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_last_written()

static MJsonNode * js_hs_get_last_written ( const MJsonNode *  params)
static

Definition at line 1966 of file mjsonrpc.cxx.

1967{
1968 if (!params) {
1969 MJSO* doc = MJSO::I();
1970 doc->D("get list of history tags for given history events that existed at give time using hs_get_last_written()");
1971 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1972 doc->P("time?", MJSON_NUMBER, "timestamp, value 0 means current time, default is 0");
1973 doc->P("events[]", MJSON_STRING, "array of history event names");
1974 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
1975 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
1976 doc->R("status", MJSON_INT, "return status");
1977 doc->R("channel", MJSON_STRING, "logger history channel name");
1978 doc->R("last_written[]", MJSON_NUMBER, "array of last-written times for each history event");
1979 return doc;
1980 }
1981
1982 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1983 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1984
1985 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
1986 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
1987 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
1988
1990
1991 MJsonNode* lw = MJsonNode::MakeArray();
1992
1993 if (!mh) {
1994 int status = HS_FILE_ERROR;
1995 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "last_written", lw);
1996 }
1997
1998 unsigned num_var = events_array->size();
1999
2000 if (tags_array->size() != num_var) {
2001 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2002 }
2003
2004 if (index_array->size() != num_var) {
2005 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2006 }
2007
2008 std::vector<std::string> event_names(num_var);
2009 std::vector<std::string> tag_names(num_var);
2010 // const char** event_name = new const char*[num_var];
2011 // const char** tag_name = new const char*[num_var];
2012 int* var_index = new int[num_var];
2013 time_t* last_written = new time_t[num_var];
2014
2015 for (unsigned i=0; i<num_var; i++) {
2016 //event_name[i] = (*events_array)[i]->GetString().c_str();
2017 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2018 event_names[i] = (*events_array)[i]->GetString();
2019 tag_names[i] = (*tags_array)[i]->GetString();
2020 var_index[i] = (*index_array)[i]->GetInt();
2021 }
2022
2023 if (/* DISABLES CODE */ (0)) {
2024 printf("time %f, num_vars %d:\n", time, num_var);
2025 for (unsigned i=0; i<num_var; i++) {
2026 printf("%d: [%s] [%s] [%d]\n", i, event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2027 }
2028 }
2029
2030 if (time == 0) {
2031 time = ::time(NULL);
2032 }
2033
2034
2035 const char** event_name = new const char*[num_var];
2036 const char** tag_name = new const char*[num_var];
2037 for (unsigned i=0; i<num_var; i++) {
2038 event_name[i] = event_names[i].c_str();
2039 tag_name[i] = tag_names[i].c_str();
2040 }
2041 int status = mh->hs_get_last_written(time, num_var, event_name, tag_name, var_index, last_written);
2042
2043 for (unsigned i=0; i<num_var; i++) {
2044 if (/* DISABLES CODE */ (0)) {
2045 printf("%d: last_written %d\n", i, (int)last_written[i]);
2046 }
2047 lw->AddToArray(MJsonNode::MakeNumber(last_written[i]));
2048 }
2049
2050 delete[] event_name;
2051 delete[] tag_name;
2052 delete[] var_index;
2053 delete[] last_written;
2054
2055 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "last_written", lw);
2056}
virtual int hs_get_last_written(time_t start_time, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], time_t last_written[])=0
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_get_tags()

static MJsonNode * js_hs_get_tags ( const MJsonNode *  params)
static

Definition at line 1888 of file mjsonrpc.cxx.

1889{
1890 if (!params) {
1891 MJSO* doc = MJSO::I();
1892 doc->D("get list of history tags for given history events that existed at give time using hs_get_tags()");
1893 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1894 doc->P("time?", MJSON_NUMBER, "timestamp, value 0 means current time, default is 0");
1895 doc->P("events[]?", MJSON_STRING, "array of history event names, default is get all events using hs_get_events()");
1896 doc->R("status", MJSON_INT, "return status");
1897 doc->R("channel", MJSON_STRING, "logger history channel name");
1898 doc->R("events[].name", MJSON_STRING, "array of history event names for each history event");
1899 doc->R("events[].status", MJSON_INT, "array of status ohistory tags for each history event");
1900 doc->R("events[].tags[]", MJSON_STRING, "array of history tags for each history event");
1901 doc->R("events[].tags[].name", MJSON_STRING, "history tag name");
1902 doc->R("events[].tags[].type", MJSON_INT, "history tag midas data type");
1903 doc->R("events[].tags[].n_data?", MJSON_INT, "history tag number of array elements, omitted if 1");
1904 return doc;
1905 }
1906
1907 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1908 double time = mjsonrpc_get_param(params, "time", NULL)->GetDouble();
1909 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
1910
1911 if (time == 0) {
1912 time = ::time(NULL);
1913 }
1914
1916
1917 MJsonNode* events = MJsonNode::MakeArray();
1918
1919 if (!mh) {
1920 int status = HS_FILE_ERROR;
1921 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1922 }
1923
1924 std::vector<std::string> event_names;
1925
1926 if (events_array && events_array->size() > 0) {
1927 for (unsigned i=0; i<events_array->size(); i++) {
1928 event_names.push_back((*events_array)[i]->GetString());
1929 }
1930 }
1931
1932 if (event_names.size() < 1) {
1933 int status = mh->hs_get_events(time, &event_names);
1934 if (status != HS_SUCCESS) {
1935 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "events", events);
1936 }
1937 }
1938
1939 for (unsigned i=0; i<event_names.size(); i++) {
1940 MJsonNode* o = MJsonNode::MakeObject();
1941 const char* event_name = event_names[i].c_str();
1942 std::vector<TAG> tags;
1943 int status = mh->hs_get_tags(event_name, time, &tags);
1944 //ss_repair_utf8(event_name); redundant!
1945 o->AddToObject("name", MJsonNode::MakeString(event_name));
1946 o->AddToObject("status", MJsonNode::MakeInt(status));
1947 MJsonNode *ta = MJsonNode::MakeArray();
1948 for (unsigned j=0; j<tags.size(); j++) {
1949 MJsonNode* to = MJsonNode::MakeObject();
1950 ss_repair_utf8(tags[j].name);
1951 to->AddToObject("name", MJsonNode::MakeString(tags[j].name));
1952 to->AddToObject("type", MJsonNode::MakeInt(tags[j].type));
1953 if (tags[j].n_data != 1) {
1954 to->AddToObject("n_data", MJsonNode::MakeInt(tags[j].n_data));
1955 }
1956 ta->AddToArray(to);
1957 }
1958 o->AddToObject("tags", ta);
1959 events->AddToArray(o);
1960 }
1961
1962 int status = HS_SUCCESS;
1963 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "events", events);
1964}
virtual int hs_get_tags(const char *event_name, time_t time_from, std::vector< TAG > *ptags)=0
get list of history variables for given event (use event names returned by hs_get_events()) that exis...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_image_retrieve()

static MJsonNode * js_hs_image_retrieve ( const MJsonNode *  params)
static

Definition at line 2936 of file mjsonrpc.cxx.

2936 {
2937 if (!params) {
2938 MJSO *doc = MJSO::I();
2939 doc->D("Get a list of history image files");
2940 doc->P("image?", MJSON_STRING, "image name as defined under /History/Images/<image>");
2941 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2942 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2943 doc->R("time[]", MJSON_ARRAYBUFFER, "array of time stamps in seconds");
2944 doc->R("filename[]", MJSON_ARRAYBUFFER, "array of file names");
2945 return doc;
2946 }
2947
2948 MJsonNode* error = NULL;
2949
2950 std::string image = mjsonrpc_get_param(params, "image", NULL)->GetString();
2951 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2952 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2953
2954 std::vector<time_t>vtime{};
2955 std::vector<std::string>vfilename{};
2956
2957 int status = hs_image_retrieve(image, start_time, end_time, vtime, vfilename);
2958 int count = 10;
2959 MJsonNode *tj = MJsonNode::MakeArray();
2960 MJsonNode *fj = MJsonNode::MakeArray();
2961
2962 for (int i=0 ; i<(int)vtime.size() ; i++) {
2963 tj->AddToArray(MJsonNode::MakeInt(vtime[i]));
2964 ss_repair_utf8(vfilename[i]);
2965 fj->AddToArray(MJsonNode::MakeString(vfilename[i].c_str()));
2966 }
2967 MJsonNode* data = MJsonNode::MakeObject();
2968 data->AddToObject("count", MJsonNode::MakeInt(count));
2969 data->AddToObject("time", tj);
2970 data->AddToObject("filename", fj);
2971
2972 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "data", data);
2973}
int hs_image_retrieve(std::string image_name, time_t start_time, time_t stop_time, std::vector< time_t > &vtime, std::vector< std::string > &vfilename)
void * data
Definition mana.cxx:268
double count
Definition mdump.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read()

static MJsonNode * js_hs_read ( const MJsonNode *  params)
static

Definition at line 2095 of file mjsonrpc.cxx.

2096{
2097 if (!params) {
2098 MJSO* doc = MJSO::I();
2099 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2100 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2101 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2102 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2103 doc->P("events[]", MJSON_STRING, "array of history event names");
2104 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2105 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2106 doc->R("status", MJSON_INT, "return status");
2107 doc->R("channel", MJSON_STRING, "logger history channel name");
2108 doc->R("data[]", MJSON_ARRAY, "array of history data");
2109 doc->R("data[].status", MJSON_INT, "status for each event");
2110 doc->R("data[].count", MJSON_INT, "number of data for each event");
2111 doc->R("data[].time[]", MJSON_NUMBER, "time data");
2112 doc->R("data[].value[]", MJSON_NUMBER, "value data");
2113 return doc;
2114 }
2115
2116 MJsonNode* error = NULL;
2117
2118 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2119 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2120 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2121
2122 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2123 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2124 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2125
2127
2128 MJsonNode* data = MJsonNode::MakeArray();
2129
2130 if (!mh) {
2131 int status = HS_FILE_ERROR;
2132 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "data", data);
2133 }
2134
2135 unsigned num_var = events_array->size();
2136
2137 if (tags_array->size() != num_var) {
2138 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2139 }
2140
2141 if (index_array->size() != num_var) {
2142 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2143 }
2144
2145 std::vector<std::string> event_names(num_var);
2146 std::vector<std::string> tag_names(num_var);
2147 int* var_index = new int[num_var];
2148 JsonHistoryBuffer** jbuf = new JsonHistoryBuffer*[num_var];
2150 int* hs_status = new int[num_var];
2151
2152 for (unsigned i=0; i<num_var; i++) {
2153 //event_name[i] = (*events_array)[i]->GetString().c_str();
2154 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2155 event_names[i] = (*events_array)[i]->GetString();
2156 tag_names[i] = (*tags_array)[i]->GetString();
2157 var_index[i] = (*index_array)[i]->GetInt();
2158 jbuf[i] = new JsonHistoryBuffer();
2159 buf[i] = jbuf[i];
2160 hs_status[i] = 0;
2161 }
2162
2163 if (/* DISABLES CODE */ (0)) {
2164 printf("time %f %f, num_vars %d:\n", start_time, end_time, num_var);
2165 for (unsigned i=0; i<num_var; i++) {
2166 printf("%d: [%s] [%s] [%d]\n", i, event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2167 }
2168 }
2169
2170 const char** event_name = new const char*[num_var];
2171 const char** tag_name = new const char*[num_var];
2172 for (unsigned i=0; i<num_var; i++) {
2173 event_name[i] = event_names[i].c_str();
2174 tag_name[i] = tag_names[i].c_str();
2175 }
2176
2177 int status = mh->hs_read_buffer(start_time, end_time, num_var, event_name, tag_name, var_index, buf, hs_status);
2178
2179 for (unsigned i=0; i<num_var; i++) {
2180 jbuf[i]->Finish();
2181
2182 MJsonNode* obj = MJsonNode::MakeObject();
2183 obj->AddToObject("status", MJsonNode::MakeInt(hs_status[i]));
2184 obj->AddToObject("count", MJsonNode::MakeInt(jbuf[i]->fCount));
2185 obj->AddToObject("time", MJsonNode::MakeJSON(jbuf[i]->fTimeJson.c_str()));
2186 obj->AddToObject("value", MJsonNode::MakeJSON(jbuf[i]->fValueJson.c_str()));
2187 data->AddToArray(obj);
2188
2189 delete jbuf[i];
2190 jbuf[i] = NULL;
2191 buf[i] = NULL;
2192 }
2193
2194 delete[] event_name;
2195 delete[] tag_name;
2196 delete[] var_index;
2197 delete[] buf;
2198 delete[] jbuf;
2199 delete[] hs_status;
2200
2201 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "data", data);
2202}
virtual int hs_read_buffer(time_t start_time, time_t end_time, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], MidasHistoryBufferInterface *buffer[], int status[])=0
returns HS_SUCCESS
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read_arraybuffer()

static MJsonNode * js_hs_read_arraybuffer ( const MJsonNode *  params)
static

Definition at line 2438 of file mjsonrpc.cxx.

2439{
2440 if (!params) {
2441 MJSO* doc = MJSO::I();
2442 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2443 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2444 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2445 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2446 doc->P("events[]", MJSON_STRING, "array of history event names");
2447 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2448 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2449 doc->R("binary data", MJSON_ARRAYBUFFER, "binary data, see documentation");
2450 return doc;
2451 }
2452
2453 MJsonNode* error = NULL;
2454
2455 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2456 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2457 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2458
2459 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2460 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2461 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2462
2464
2465 if (!mh) {
2466 int status = HS_FILE_ERROR;
2467 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
2468 }
2469
2470 size_t num_var = events_array->size();
2471
2472 if (tags_array->size() != num_var) {
2473 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2474 }
2475
2476 if (index_array->size() != num_var) {
2477 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2478 }
2479
2480 std::vector<std::string> event_names(num_var);
2481 std::vector<std::string> tag_names(num_var);
2482 int* var_index = new int[num_var];
2483 BinaryHistoryBuffer** jbuf = new BinaryHistoryBuffer*[num_var];
2485 int* hs_status = new int[num_var];
2486
2487 for (size_t i=0; i<num_var; i++) {
2488 //event_name[i] = (*events_array)[i]->GetString().c_str();
2489 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2490 event_names[i] = (*events_array)[i]->GetString();
2491 tag_names[i] = (*tags_array)[i]->GetString();
2492 var_index[i] = (*index_array)[i]->GetInt();
2493 jbuf[i] = new BinaryHistoryBuffer();
2494 buf[i] = jbuf[i];
2495 hs_status[i] = 0;
2496 }
2497
2498 if (/* DISABLES CODE */ (0)) {
2499 printf("time %f %f, num_vars %d:\n", start_time, end_time, int(num_var));
2500 for (size_t i=0; i<num_var; i++) {
2501 printf("%d: [%s] [%s] [%d]\n", int(i), event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2502 }
2503 }
2504
2505 const char** event_name = new const char*[num_var];
2506 const char** tag_name = new const char*[num_var];
2507 for (unsigned i=0; i<num_var; i++) {
2508 event_name[i] = event_names[i].c_str();
2509 tag_name[i] = tag_names[i].c_str();
2510 }
2511
2512 int status = mh->hs_read_buffer(start_time, end_time, num_var, event_name, tag_name, var_index, buf, hs_status);
2513
2514 size_t num_values = 0;
2515
2516 for (unsigned i=0; i<num_var; i++) {
2517 jbuf[i]->Finish();
2518 num_values += jbuf[i]->fValues.size();
2519 }
2520
2521 // NB: beware of 32-bit integer overflow. all values are now 64-bit size_t, overflow should not happen.
2522 size_t p0_size = sizeof(double)*(2+2*num_var+2*num_values);
2523
2524 size_t size_limit = 1000*1024*1024;
2525
2526 if (p0_size > size_limit) {
2527 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Refusing to return %zu bytes of history data, limit is %zu bytes\n", p0_size, size_limit);
2528
2529 for (size_t i=0; i<num_var; i++) {
2530 delete jbuf[i];
2531 jbuf[i] = NULL;
2532 buf[i] = NULL;
2533 }
2534
2535 delete[] event_name;
2536 delete[] tag_name;
2537 delete[] var_index;
2538 delete[] buf;
2539 delete[] jbuf;
2540 delete[] hs_status;
2541
2542 return mjsonrpc_make_error(-32603, "Internal error", "Too much history data");
2543 }
2544
2545 double* p0 = (double*)malloc(p0_size);
2546
2547 if (p0 == NULL) {
2548 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Cannot allocate return buffer %d bytes\n", int(p0_size));
2549
2550 for (size_t i=0; i<num_var; i++) {
2551 delete jbuf[i];
2552 jbuf[i] = NULL;
2553 buf[i] = NULL;
2554 }
2555
2556 delete[] event_name;
2557 delete[] tag_name;
2558 delete[] var_index;
2559 delete[] buf;
2560 delete[] jbuf;
2561 delete[] hs_status;
2562
2563 return mjsonrpc_make_error(-32603, "Internal error", "Cannot allocate buffer, too much data");
2564 }
2565
2566 double *pptr = p0;
2567
2568 //
2569 // Binary data format:
2570 //
2571 // - hs_read() status
2572 // - num_var
2573 // - hs_status[0..num_var-1]
2574 // - num_values[0..num_var-1]
2575 // - data for var0:
2576 // - t[0][0], v[0][0] ... t[0][num_values[0]-1], v[0][num_values[0]-1]
2577 // - data for var1:
2578 // - t[1][0], v[1][0] ... t[1][num_values[1]-1], v[1][num_values[1]-1]
2579 // ...
2580 // - data for last variable:
2581 // - t[num_var-1][0], v[num_var-1][0] ... t[num_var-1][num_values[num_var-1]-1], v[num_var-1][num_values[num_var-1]-1]
2582 //
2583
2584 *pptr++ = status;
2585 *pptr++ = num_var;
2586
2587 for (size_t i=0; i<num_var; i++) {
2588 *pptr++ = hs_status[i];
2589 }
2590
2591 for (size_t i=0; i<num_var; i++) {
2592 *pptr++ = jbuf[i]->fValues.size();
2593 }
2594
2595 for (size_t i=0; i<num_var; i++) {
2596 size_t nv = jbuf[i]->fValues.size();
2597 for (size_t j=0; j<nv; j++) {
2598 *pptr++ = jbuf[i]->fTimes[j];
2599 *pptr++ = jbuf[i]->fValues[j];
2600 }
2601
2602 delete jbuf[i];
2603 jbuf[i] = NULL;
2604 buf[i] = NULL;
2605 }
2606
2607 //printf("p0_size %d, %d/%d\n", (int)p0_size, (int)(pptr-p0), (int)((pptr-p0)*sizeof(double)));
2608
2609 assert(p0_size == ((pptr-p0)*sizeof(double)));
2610
2611 delete[] event_name;
2612 delete[] tag_name;
2613 delete[] var_index;
2614 delete[] buf;
2615 delete[] jbuf;
2616 delete[] hs_status;
2617
2618 MJsonNode* result = MJsonNode::MakeArrayBuffer((char*)p0, p0_size);
2619
2620 return result;
2621}
std::vector< double > fValues
std::vector< double > fTimes
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read_binned()

static MJsonNode * js_hs_read_binned ( const MJsonNode *  params)
static

Definition at line 2204 of file mjsonrpc.cxx.

2205{
2206 if (!params) {
2207 MJSO* doc = MJSO::I();
2208 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2209 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2210 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2211 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2212 doc->P("num_bins", MJSON_INT, "number of time bins");
2213 doc->P("events[]", MJSON_STRING, "array of history event names");
2214 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2215 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2216 doc->R("status", MJSON_INT, "return status");
2217 doc->R("channel", MJSON_STRING, "logger history channel name");
2218 doc->R("data[]", MJSON_ARRAY, "array of history data");
2219 doc->R("data[].status", MJSON_INT, "status for each event");
2220 doc->R("data[].num_entries", MJSON_INT, "number of data points for each event");
2221 doc->R("data[].count[]", MJSON_INT, "number of data points for each bin");
2222 doc->R("data[].mean[]", MJSON_NUMBER, "mean for each bin");
2223 doc->R("data[].rms[]", MJSON_NUMBER, "rms for each bin");
2224 doc->R("data[].min[]", MJSON_NUMBER, "minimum value for each bin");
2225 doc->R("data[].max[]", MJSON_NUMBER, "maximum value for each bin");
2226 doc->R("data[].bins_first_time[]", MJSON_NUMBER, "first data point in each bin");
2227 doc->R("data[].bins_first_value[]", MJSON_NUMBER, "first data point in each bin");
2228 doc->R("data[].bins_last_time[]", MJSON_NUMBER, "last data point in each bin");
2229 doc->R("data[].bins_last_value[]", MJSON_NUMBER, "last data point in each bin");
2230 doc->R("data[].last_time", MJSON_NUMBER, "time of last data entry");
2231 doc->R("data[].last_value", MJSON_NUMBER, "value of last data entry");
2232 return doc;
2233 }
2234
2235 MJsonNode* error = NULL;
2236
2237 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2238 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2239 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2240 int num_bins = mjsonrpc_get_param(params, "num_bins", &error)->GetInt(); if (error) return error;
2241
2242 if (num_bins < 1) {
2243 return mjsonrpc_make_error(-32602, "Invalid params", "Value of num_bins should be 1 or more");
2244 }
2245
2246 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2247 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2248 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2249
2251
2252 MJsonNode* data = MJsonNode::MakeArray();
2253
2254 if (!mh) {
2255 int status = HS_FILE_ERROR;
2256 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "data", data);
2257 }
2258
2259 unsigned num_var = events_array->size();
2260
2261 if (num_var < 1) {
2262 return mjsonrpc_make_error(-32602, "Invalid params", "Array of events should have 1 or more elements");
2263 }
2264
2265 if (tags_array->size() != num_var) {
2266 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2267 }
2268
2269 if (index_array->size() != num_var) {
2270 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2271 }
2272
2273 std::vector<std::string> event_names(num_var);
2274 std::vector<std::string> tag_names(num_var);
2275 //const char** event_name = new const char*[num_var];
2276 //const char** tag_name = new const char*[num_var];
2277 int* var_index = new int[num_var];
2278
2279 int* num_entries = new int[num_var];
2280 time_t* last_time = new time_t[num_var];
2281 double* last_value = new double[num_var];
2282 int* hs_status = new int[num_var];
2283
2284 int** count_bins = new int*[num_var];
2285 double** mean_bins = new double*[num_var];
2286 double** rms_bins = new double*[num_var];
2287 double** min_bins = new double*[num_var];
2288 double** max_bins = new double*[num_var];
2289
2290 time_t** bins_first_time = new time_t*[num_var];
2291 time_t** bins_last_time = new time_t*[num_var];
2292
2293 double** bins_first_value = new double*[num_var];
2294 double** bins_last_value = new double*[num_var];
2295
2296 for (unsigned i=0; i<num_var; i++) {
2297 //event_name[i] = (*events_array)[i]->GetString().c_str();
2298 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2299 event_names[i] = (*events_array)[i]->GetString();
2300 tag_names[i] = (*tags_array)[i]->GetString();
2301 var_index[i] = (*index_array)[i]->GetInt();
2302 num_entries[i] = 0;
2303 last_time[i] = 0;
2304 last_value[i] = 0;
2305 hs_status[i] = 0;
2306 count_bins[i] = new int[num_bins];
2307 mean_bins[i] = new double[num_bins];
2308 rms_bins[i] = new double[num_bins];
2309 min_bins[i] = new double[num_bins];
2310 max_bins[i] = new double[num_bins];
2311
2312 bins_first_time[i] = new time_t[num_bins];
2313 bins_last_time[i] = new time_t[num_bins];
2314
2315 bins_first_value[i] = new double[num_bins];
2316 bins_last_value[i] = new double[num_bins];
2317 }
2318
2319 if (/* DISABLES CODE */ (0)) {
2320 printf("time %f %f, num_vars %d:\n", start_time, end_time, num_var);
2321 for (unsigned i=0; i<num_var; i++) {
2322 printf("%d: [%s] [%s] [%d]\n", i, event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2323 }
2324 }
2325
2326 const char** event_name = new const char*[num_var];
2327 const char** tag_name = new const char*[num_var];
2328 for (unsigned i=0; i<num_var; i++) {
2329 event_name[i] = event_names[i].c_str();
2330 tag_name[i] = tag_names[i].c_str();
2331 }
2332
2333 int status = mh->hs_read_binned(start_time, end_time, num_bins, num_var, event_name, tag_name, var_index, num_entries, count_bins, mean_bins, rms_bins, min_bins, max_bins, bins_first_time, bins_first_value, bins_last_time, bins_last_value, last_time, last_value, hs_status);
2334
2335 for (unsigned i=0; i<num_var; i++) {
2336 MJsonNode* obj = MJsonNode::MakeObject();
2337 obj->AddToObject("status", MJsonNode::MakeInt(hs_status[i]));
2338 obj->AddToObject("num_entries", MJsonNode::MakeInt(num_entries[i]));
2339
2340 MJsonNode* a1 = MJsonNode::MakeArray();
2341 MJsonNode* a2 = MJsonNode::MakeArray();
2342 MJsonNode* a3 = MJsonNode::MakeArray();
2343 MJsonNode* a4 = MJsonNode::MakeArray();
2344 MJsonNode* a5 = MJsonNode::MakeArray();
2345
2346 MJsonNode* b1 = MJsonNode::MakeArray();
2347 MJsonNode* b2 = MJsonNode::MakeArray();
2348 MJsonNode* b3 = MJsonNode::MakeArray();
2349 MJsonNode* b4 = MJsonNode::MakeArray();
2350
2351 for (int j=0; j<num_bins; j++) {
2352 a1->AddToArray(MJsonNode::MakeInt(count_bins[i][j]));
2353 a2->AddToArray(MJsonNode::MakeNumber(mean_bins[i][j]));
2354 a3->AddToArray(MJsonNode::MakeNumber(rms_bins[i][j]));
2355 a4->AddToArray(MJsonNode::MakeNumber(min_bins[i][j]));
2356 a5->AddToArray(MJsonNode::MakeNumber(max_bins[i][j]));
2357
2358 b1->AddToArray(MJsonNode::MakeNumber(bins_first_time[i][j]));
2359 b2->AddToArray(MJsonNode::MakeNumber(bins_first_value[i][j]));
2360 b3->AddToArray(MJsonNode::MakeNumber(bins_last_time[i][j]));
2361 b4->AddToArray(MJsonNode::MakeNumber(bins_last_value[i][j]));
2362 }
2363
2364 obj->AddToObject("count", a1);
2365 obj->AddToObject("mean", a2);
2366 obj->AddToObject("rms", a3);
2367 obj->AddToObject("min", a4);
2368 obj->AddToObject("max", a5);
2369 obj->AddToObject("bins_first_time", b1);
2370 obj->AddToObject("bins_first_value", b2);
2371 obj->AddToObject("bins_last_time", b3);
2372 obj->AddToObject("bins_last_value", b4);
2373 obj->AddToObject("last_time", MJsonNode::MakeNumber(last_time[i]));
2374 obj->AddToObject("last_value", MJsonNode::MakeNumber(last_value[i]));
2375 data->AddToArray(obj);
2376
2377 delete count_bins[i];
2378 delete mean_bins[i];
2379 delete rms_bins[i];
2380 delete min_bins[i];
2381 delete max_bins[i];
2382
2383 delete bins_first_time[i];
2384 delete bins_first_value[i];
2385 delete bins_last_time[i];
2386 delete bins_last_value[i];
2387 }
2388
2389 delete[] count_bins;
2390 delete[] mean_bins;
2391 delete[] rms_bins;
2392 delete[] min_bins;
2393 delete[] max_bins;
2394
2395 delete[] bins_first_time;
2396 delete[] bins_first_value;
2397 delete[] bins_last_time;
2398 delete[] bins_last_value;
2399
2400 delete[] event_name;
2401 delete[] tag_name;
2402 delete[] var_index;
2403
2404 delete[] num_entries;
2405 delete[] last_time;
2406 delete[] last_value;
2407 delete[] hs_status;
2408
2409 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name), "data", data);
2410}
virtual int hs_read_binned(time_t start_time, time_t end_time, int num_bins, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], int num_entries[], int *count_bins[], double *mean_bins[], double *rms_bins[], double *min_bins[], double *max_bins[], time_t *bins_first_time[], double *bins_first_value[], time_t *bins_last_time[], double *bins_last_value[], time_t last_time[], double last_value[], int status[])=0
returns HS_SUCCESS
DWORD last_time
Definition mana.cxx:3070
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_read_binned_arraybuffer()

static MJsonNode * js_hs_read_binned_arraybuffer ( const MJsonNode *  params)
static

Definition at line 2623 of file mjsonrpc.cxx.

2624{
2625 if (!params) {
2626 MJSO* doc = MJSO::I();
2627 doc->D("get history data for given history events that existed at give time using hs_read_buffer()");
2628 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
2629 doc->P("start_time", MJSON_NUMBER, "start time of the data");
2630 doc->P("end_time", MJSON_NUMBER, "end time of the data");
2631 doc->P("num_bins", MJSON_INT, "number of time bins");
2632 doc->P("events[]", MJSON_STRING, "array of history event names");
2633 doc->P("tags[]", MJSON_STRING, "array of history event tag names");
2634 doc->P("index[]", MJSON_STRING, "array of history event tag array indices");
2635 doc->R("binary data", MJSON_ARRAYBUFFER, "binary data, see documentation");
2636 return doc;
2637 }
2638
2639 MJsonNode* error = NULL;
2640
2641 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
2642 double start_time = mjsonrpc_get_param(params, "start_time", &error)->GetDouble(); if (error) return error;
2643 double end_time = mjsonrpc_get_param(params, "end_time", &error)->GetDouble(); if (error) return error;
2644 int inum_bins = mjsonrpc_get_param(params, "num_bins", &error)->GetInt(); if (error) return error;
2645
2646 if (inum_bins < 1) {
2647 return mjsonrpc_make_error(-32602, "Invalid params", "Value of num_bins should be 1 or more");
2648 }
2649
2650 size_t num_bins = inum_bins;
2651
2652 const MJsonNodeVector* events_array = mjsonrpc_get_param_array(params, "events", NULL);
2653 const MJsonNodeVector* tags_array = mjsonrpc_get_param_array(params, "tags", NULL);
2654 const MJsonNodeVector* index_array = mjsonrpc_get_param_array(params, "index", NULL);
2655
2657
2658 if (!mh) {
2659 int status = HS_FILE_ERROR;
2660 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
2661 }
2662
2663 size_t num_var = events_array->size();
2664
2665 if (num_var < 1) {
2666 return mjsonrpc_make_error(-32602, "Invalid params", "Array of events should have 1 or more elements");
2667 }
2668
2669 if (tags_array->size() != num_var) {
2670 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and tags should have the same length");
2671 }
2672
2673 if (index_array->size() != num_var) {
2674 return mjsonrpc_make_error(-32602, "Invalid params", "Arrays events and index should have the same length");
2675 }
2676
2677 std::vector<std::string> event_names(num_var);
2678 std::vector<std::string> tag_names(num_var);
2679 //const char** event_name = new const char*[num_var];
2680 //const char** tag_name = new const char*[num_var];
2681 int* var_index = new int[num_var];
2682
2683 int* num_entries = new int[num_var];
2684 time_t* last_time = new time_t[num_var];
2685 double* last_value = new double[num_var];
2686 int* hs_status = new int[num_var];
2687
2688 int** count_bins = new int*[num_var];
2689 double** mean_bins = new double*[num_var];
2690 double** rms_bins = new double*[num_var];
2691 double** min_bins = new double*[num_var];
2692 double** max_bins = new double*[num_var];
2693
2694 time_t** bins_first_time = new time_t*[num_var];
2695 time_t** bins_last_time = new time_t*[num_var];
2696
2697 double** bins_first_value = new double*[num_var];
2698 double** bins_last_value = new double*[num_var];
2699
2700 for (unsigned i=0; i<num_var; i++) {
2701 //event_name[i] = (*events_array)[i]->GetString().c_str();
2702 //tag_name[i] = (*tags_array)[i]->GetString().c_str();
2703 event_names[i] = (*events_array)[i]->GetString();
2704 tag_names[i] = (*tags_array)[i]->GetString();
2705 var_index[i] = (*index_array)[i]->GetInt();
2706 num_entries[i] = 0;
2707 last_time[i] = 0;
2708 last_value[i] = 0;
2709 hs_status[i] = 0;
2710 count_bins[i] = new int[num_bins];
2711 mean_bins[i] = new double[num_bins];
2712 rms_bins[i] = new double[num_bins];
2713 min_bins[i] = new double[num_bins];
2714 max_bins[i] = new double[num_bins];
2715 bins_first_time[i] = new time_t[num_bins];
2716 bins_last_time[i] = new time_t[num_bins];
2717 bins_first_value[i] = new double[num_bins];
2718 bins_last_value[i] = new double[num_bins];
2719 }
2720
2721 if (/* DISABLES CODE */ (0)) {
2722 printf("time %f %f, num_vars %d:\n", start_time, end_time, int(num_var));
2723 for (size_t i=0; i<num_var; i++) {
2724 printf("%d: [%s] [%s] [%d]\n", int(i), event_names[i].c_str(), tag_names[i].c_str(), var_index[i]);
2725 }
2726 }
2727
2728 const char** event_name = new const char*[num_var];
2729 const char** tag_name = new const char*[num_var];
2730 for (size_t i=0; i<num_var; i++) {
2731 event_name[i] = event_names[i].c_str();
2732 tag_name[i] = tag_names[i].c_str();
2733 }
2734
2735 int status = mh->hs_read_binned(start_time, end_time, num_bins, num_var, event_name, tag_name, var_index, num_entries, count_bins, mean_bins, rms_bins, min_bins, max_bins, bins_first_time, bins_first_value, bins_last_time, bins_last_value, last_time, last_value, hs_status);
2736
2737 // NB: beware of 32-bit integer overflow: all variables are now 64-bit size_t, overflow should not happen
2738 size_t p0_size = sizeof(double)*(5+4*num_var+9*num_var*num_bins);
2739
2740 size_t size_limit = 100*1024*1024;
2741
2742 if (p0_size > size_limit) {
2743 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Refusing to return %d bytes. limit is %d bytes\n", int(p0_size), int(size_limit));
2744
2745 for (size_t i=0; i<num_var; i++) {
2746 delete count_bins[i];
2747 delete mean_bins[i];
2748 delete rms_bins[i];
2749 delete min_bins[i];
2750 delete max_bins[i];
2751 delete bins_first_time[i];
2752 delete bins_first_value[i];
2753 delete bins_last_time[i];
2754 delete bins_last_value[i];
2755 }
2756
2757 delete[] count_bins;
2758 delete[] mean_bins;
2759 delete[] rms_bins;
2760 delete[] min_bins;
2761 delete[] max_bins;
2762
2763 delete[] bins_first_time;
2764 delete[] bins_first_value;
2765 delete[] bins_last_time;
2766 delete[] bins_last_value;
2767
2768 delete[] event_name;
2769 delete[] tag_name;
2770 delete[] var_index;
2771
2772 delete[] num_entries;
2773 delete[] last_time;
2774 delete[] last_value;
2775 delete[] hs_status;
2776
2777 return mjsonrpc_make_error(-32603, "Internal error", "Refuse to return too much data");
2778 }
2779
2780 double* p0 = (double*)malloc(p0_size);
2781
2782 if (p0 == NULL) {
2783 cm_msg(MERROR, "js_hs_read_binned_arraybuffer", "Cannot allocate return buffer %d bytes\n", int(p0_size));
2784
2785 for (size_t i=0; i<num_var; i++) {
2786 delete count_bins[i];
2787 delete mean_bins[i];
2788 delete rms_bins[i];
2789 delete min_bins[i];
2790 delete max_bins[i];
2791 delete bins_first_time[i];
2792 delete bins_first_value[i];
2793 delete bins_last_time[i];
2794 delete bins_last_value[i];
2795 }
2796
2797 delete[] count_bins;
2798 delete[] mean_bins;
2799 delete[] rms_bins;
2800 delete[] min_bins;
2801 delete[] max_bins;
2802
2803 delete[] bins_first_time;
2804 delete[] bins_first_value;
2805 delete[] bins_last_time;
2806 delete[] bins_last_value;
2807
2808 delete[] event_name;
2809 delete[] tag_name;
2810 delete[] var_index;
2811
2812 delete[] num_entries;
2813 delete[] last_time;
2814 delete[] last_value;
2815 delete[] hs_status;
2816
2817 return mjsonrpc_make_error(-32603, "Internal error", "Cannot allocate buffer, too much data");
2818 }
2819
2820 double *pptr = p0;
2821
2822 //
2823 // Binary data format:
2824 //
2825 // * header
2826 // -- hs_read() status
2827 // -- start_time
2828 // -- end_time
2829 // -- num_bins
2830 // -- num_var
2831 // * per variable info
2832 // -- hs_status[0..num_var-1]
2833 // -- num_entries[0..num_var-1]
2834 // -- last_time[0..num_var-1]
2835 // -- last_value[0..num_var-1]
2836 // * data for var0 bin0
2837 // -- count - number of entries in this bin
2838 // -- mean - mean value
2839 // -- rms - rms value
2840 // -- min - minimum value
2841 // -- max - maximum value
2842 // -- bins_first_time - first data point in each bin
2843 // -- bins_first_value
2844 // -- bins_last_time - last data point in each bin
2845 // -- bins_last_value
2846 // - data for var0 bin1
2847 // - ... bin[num_bins-1]
2848 // - data for var1 bin0
2849 // - ...
2850 // - data for var[num_vars-1] bin[0]
2851 // - ...
2852 // - data for var[num_vars-1] bin[num_bins-1]
2853 //
2854
2855 *pptr++ = status;
2856 *pptr++ = start_time;
2857 *pptr++ = end_time;
2858 *pptr++ = num_bins;
2859 *pptr++ = num_var;
2860
2861 for (unsigned i=0; i<num_var; i++) {
2862 *pptr++ = hs_status[i];
2863 }
2864
2865 for (unsigned i=0; i<num_var; i++) {
2866 *pptr++ = num_entries[i];
2867 }
2868
2869 for (unsigned i=0; i<num_var; i++) {
2870 *pptr++ = last_time[i];
2871 }
2872
2873 for (unsigned i=0; i<num_var; i++) {
2874 *pptr++ = last_value[i];
2875 }
2876
2877 for (size_t i=0; i<num_var; i++) {
2878 for (size_t j=0; j<num_bins; j++) {
2879 *pptr++ = count_bins[i][j];
2880 *pptr++ = mean_bins[i][j];
2881 *pptr++ = rms_bins[i][j];
2882 *pptr++ = min_bins[i][j];
2883 *pptr++ = max_bins[i][j];
2884 *pptr++ = bins_first_time[i][j];
2885 *pptr++ = bins_first_value[i][j];
2886 *pptr++ = bins_last_time[i][j];
2887 *pptr++ = bins_last_value[i][j];
2888 }
2889
2890 delete count_bins[i];
2891 delete mean_bins[i];
2892 delete rms_bins[i];
2893 delete min_bins[i];
2894 delete max_bins[i];
2895 delete bins_first_time[i];
2896 delete bins_first_value[i];
2897 delete bins_last_time[i];
2898 delete bins_last_value[i];
2899 }
2900
2901 //printf("p0_size %d, %d/%d\n", (int)p0_size, (int)(pptr-p0), (int)((pptr-p0)*sizeof(double)));
2902
2903 assert(p0_size == ((pptr-p0)*sizeof(double)));
2904
2905 delete[] count_bins;
2906 delete[] mean_bins;
2907 delete[] rms_bins;
2908 delete[] min_bins;
2909 delete[] max_bins;
2910
2911 delete[] bins_first_time;
2912 delete[] bins_first_value;
2913 delete[] bins_last_time;
2914 delete[] bins_last_value;
2915
2916 delete[] event_name;
2917 delete[] tag_name;
2918 delete[] var_index;
2919
2920 delete[] num_entries;
2921 delete[] last_time;
2922 delete[] last_value;
2923 delete[] hs_status;
2924
2925 MJsonNode* result = MJsonNode::MakeArrayBuffer((char*)p0, p0_size);
2926
2927 return result;
2928}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_hs_reopen()

static MJsonNode * js_hs_reopen ( const MJsonNode *  params)
static

Definition at line 1863 of file mjsonrpc.cxx.

1864{
1865 if (!params) {
1866 MJSO* doc = MJSO::I();
1867 doc->D("reopen the history channel to make sure we see the latest list of events using hs_clear_cache()");
1868 doc->P("channel?", MJSON_STRING, "midas history channel, default is the default reader channel");
1869 doc->R("status", MJSON_INT, "return status of hs_get_events()");
1870 doc->R("channel", MJSON_STRING, "logger history channel name");
1871 return doc;
1872 }
1873
1874 std::string channel = mjsonrpc_get_param(params, "channel", NULL)->GetString();
1875
1877
1878 if (!mh) {
1879 int status = HS_FILE_ERROR;
1880 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
1881 }
1882
1883 int status = mh->hs_clear_cache();
1884
1885 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "channel", MJsonNode::MakeString(mh->name));
1886}
virtual int hs_clear_cache()=0
clear internal cache, returns HS_SUCCESS
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_make_subdir()

static MJsonNode * js_make_subdir ( const MJsonNode *  params)
static

Definition at line 4168 of file mjsonrpc.cxx.

4169{
4170 if (!params) {
4171 MJSO* doc = MJSO::I();
4172 doc->D("js_make_subdir");
4173 doc->P("subdir", MJSON_STRING, "Create folder experiment_directory/userfiles/subdir");
4174 doc->R("status", MJSON_INT, "return status of midas library calls");
4175 doc->R("path", MJSON_STRING, "Search path");
4176 return doc;
4177 }
4178
4179 MJsonNode* error = NULL;
4180
4181 std::string subdir = mjsonrpc_get_param(params, "subdir", &error)->GetString(); if (error) return error;
4182
4183 /*---- Not allowed to contain ../ - safety feature ----*/
4184 if (subdir.find("..") != std::string::npos) {
4185 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The subdir is not permitted"));
4186 }
4187
4188 int status;
4189 HNDLE hDB;
4190
4192
4193 if (status != DB_SUCCESS) {
4194 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
4195 }
4196
4197 std::string path = cm_expand_env(cm_get_path().c_str());
4198 if (path[path.length()-1] != DIR_SEPARATOR) {
4199 path += DIR_SEPARATOR_STR;
4200 }
4201 path += "userfiles";
4202
4203 // Check if the userfiles folder exists
4204 if (access(path.c_str(), F_OK) != 0) {
4205 // Create the path if it doesn't exist
4206 if (mkdir(path.c_str(), 0777) != 0) {
4207 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4208 }
4209 }
4210
4211 // Add subdir to userfiles
4212 if (subdir.length() > 0) {
4213 if (subdir[0] != DIR_SEPARATOR) {
4214 path += DIR_SEPARATOR_STR;
4215 }
4216 path += subdir;
4217 }
4218 // Check if the subdir exisits in userfiles, otherwise create it
4219 if (access(path.c_str(), F_OK) != 0) {
4220 // Create the path if it doesn't exist
4221 if (mkdir(path.c_str(), 0777) != 0) {
4222 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create subdirectory"));
4223 }
4224 }
4225
4226
4227 MJsonNode* r = MJsonNode::MakeObject();
4228 r->AddToObject("status", MJsonNode::MakeInt(SUCCESS));
4229 ss_repair_utf8(path);
4230 r->AddToObject("path", MJsonNode::MakeString(path.c_str()));
4231 return mjsonrpc_make_result(r);
4232}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_read_binary_file()

static MJsonNode * js_read_binary_file ( const MJsonNode *  params)
static

Definition at line 4520 of file mjsonrpc.cxx.

4520 {
4521 if (!params) {
4522 MJSO* doc = MJSO::I();
4523 doc->D("js_read_binary_file");
4524 doc->P("filename", MJSON_STRING, "File name, read from experiment_directory/userfiles/filename");
4525 doc->R("binary data", MJSON_ARRAYBUFFER, "Binary file content");
4526 doc->R("status", MJSON_INT, "Return status of midas library calls");
4527 doc->R("error", MJSON_STRING, "Error text");
4528 return doc;
4529 }
4530
4531 MJsonNode* error = NULL;
4532 std::string filename = mjsonrpc_get_param(params, "filename", &error)->GetString();
4533 if (error) return error;
4534
4535 /*---- filename should not contain the following - safety feature */
4536 if (filename.find("..") != std::string::npos ||
4537 filename.find("*") != std::string::npos) {
4538 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("The filename is not permitted"));
4539 }
4540
4541 int status;
4542 HNDLE hDB;
4543
4545
4546 if (status != DB_SUCCESS) {
4547 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString("cm_get_experiment_database() error"));
4548 }
4549
4550 std::string path = cm_expand_env(cm_get_path().c_str());
4551 if (path[path.length()-1] != DIR_SEPARATOR) {
4552 path += DIR_SEPARATOR_STR;
4553 }
4554 path += "userfiles";
4555
4556 // Check if the userfiles folder exists
4557 if (access(path.c_str(), F_OK) != 0) {
4558 // Create the path if it doesn't exist
4559 if (mkdir(path.c_str(), 0777) != 0) {
4560 return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM), "error", MJsonNode::MakeString("Failed to create the userfiles folder"));
4561 }
4562 }
4563
4564 path += DIR_SEPARATOR_STR;
4565 path += filename;
4566
4567 FILE* fp = fopen(path.c_str(), "rb");
4568 if (!fp) {
4570 char errstr[256];
4571 sprintf(errstr, "fopen() errno %d (%s)", errno, strerror(errno));
4572 ss_repair_utf8(errstr);
4573 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status), "error", MJsonNode::MakeString(errstr));
4574 }
4575
4576 fseek(fp, 0, SEEK_END);
4577 size_t file_size = ftell(fp);
4578 rewind(fp);
4579
4580 char* buffer = new char[file_size];
4581 fread(buffer, file_size, 1, fp);
4582 // maybe not needed here
4583 //buffer[file_size] = '\0';
4584 fclose(fp);
4585
4587 std::string errstr = "no error";
4588
4589 MJsonNode* result = MJsonNode::MakeArrayBuffer(buffer, file_size);
4590 return result;
4591}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ js_ss_millitime()

static MJsonNode * js_ss_millitime ( const MJsonNode *  params)
static

Definition at line 3928 of file mjsonrpc.cxx.

3929{
3930 if (!params) {
3931 MJSO *doc = MJSO::I();
3932 doc->D("get current MIDAS time using ss_millitime()");
3933 doc->P(NULL, 0, "there are no input parameters");
3934 doc->R(NULL, MJSON_INT, "current value of ss_millitime()");
3935 return doc;
3936 }
3937
3938 return mjsonrpc_make_result(MJsonNode::MakeNumber(ss_millitime()));
3939}
DWORD ss_millitime()
Definition system.cxx:3472
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MatchEvent()

static void MatchEvent ( const std::string  buffer_name,
const EVENT_HEADER pevent 
)
static

Definition at line 3715 of file mjsonrpc.cxx.

3716{
3717 std::lock_guard<std::mutex> guard(gEventStashMutex);
3718 for (EventStashEntry* s : gEventStash) {
3719 if (s->buffer_name != buffer_name)
3720 continue;
3721 if (bm_match_event(s->event_id, s->trigger_mask, pevent)) {
3722 s->ReplaceEvent(pevent);
3723 //s->Print(); printf(", matched\n");
3724 }
3725 }
3726}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_get_param_array()

const MJsonNodeVector * mjsonrpc_get_param_array ( const MJsonNode *  params,
const char *  name,
MJsonNode **  error 
)

Definition at line 201 of file mjsonrpc.cxx.

202{
203 // NULL params is a request for documentation, return NULL
204 if (!params) {
205 if (error)
206 *error = MJsonNode::MakeObject();
207 return NULL;
208 }
209
210 const MJsonNode* node = mjsonrpc_get_param(params, name, error);
211
212 // handle error return from mjsonrpc_get_param()
213 if (error && *error) {
214 return NULL;
215 }
216
217 const MJsonNodeVector* v = node->GetArray();
218
219 if (!v) {
220 if (error)
221 *error = mjsonrpc_make_error(-32602, "Invalid params", (std::string("parameter must be an array: ") + name).c_str());
222 return NULL;
223 }
224
225 if (error)
226 *error = NULL;
227 return v;
228}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_handle_request()

static MJsonNode * mjsonrpc_handle_request ( const MJsonNode *  request)
static

Definition at line 5205 of file mjsonrpc.cxx.

5206{
5207 // find required request elements
5208 const MJsonNode* version = request->FindObjectNode("jsonrpc");
5209 const MJsonNode* method = request->FindObjectNode("method");
5210 const MJsonNode* params = request->FindObjectNode("params");
5211 const MJsonNode* id = request->FindObjectNode("id");
5212
5213 std::string bad = "";
5214
5215 if (!version)
5216 add(&bad, "jsonrpc version is missing");
5217 if (!method)
5218 add(&bad, "method is missing");
5219 if (!params)
5220 add(&bad, "params is missing");
5221 if (!id)
5222 add(&bad, "id is missing");
5223
5224 if (version && (version->GetType() != MJSON_STRING))
5225 add(&bad, "jsonrpc version is not a string");
5226 if (version && (version->GetString() != "2.0"))
5227 add(&bad, "jsonrpc version is not 2.0");
5228
5229 if (method && (method->GetType() != MJSON_STRING))
5230 add(&bad, "method is not a string");
5231
5232 if (!method || bad.length() > 0) {
5233 MJsonNode* response = mjsonrpc_make_error(-32600, "Invalid request", bad.c_str());
5234 response->AddToObject("jsonrpc", MJsonNode::MakeString("2.0"));
5235 if (id) {
5236 response->AddToObject("id", id->Copy());
5237 } else {
5238 response->AddToObject("id", MJsonNode::MakeNull());
5239 }
5240
5241 if (mjsonrpc_debug) {
5242 printf("mjsonrpc: invalid request: reply:\n");
5243 printf("%s\n", response->Stringify().c_str());
5244 printf("\n");
5245 }
5246
5247 return response;
5248 }
5249
5250 double start_time = 0;
5251
5252 if (mjsonrpc_time) {
5253 start_time = GetTimeSec();
5254 }
5255
5256 const std::string ms = method->GetString();
5257 const char* m = ms.c_str();
5258
5259 MJsonNode* result = NULL;
5260
5261 // special built-in methods
5262
5263 if (strcmp(m, "echo") == 0) {
5264 result = mjsonrpc_make_result(request->Copy());
5265 } else if (strcmp(m, "error") == 0) {
5266 result = mjsonrpc_make_error(1, "test error", "test error");
5267 } else if (strcmp(m, "invalid_json") == 0) {
5268 if (mjsonrpc_debug) {
5269 printf("mjsonrpc: reply with invalid json\n");
5270 }
5271 return MJsonNode::MakeJSON("this is invalid json data");
5272 } else if (strcmp(m, "test_nan_inf") == 0) {
5273 double one = 1;
5274 double zero = 0;
5275 double nan = zero/zero;
5276 double plusinf = one/zero;
5277 double minusinf = -one/zero;
5278 MJsonNode* n = MJsonNode::MakeArray();
5279 n->AddToArray(MJsonNode::MakeNumber(nan));
5280 n->AddToArray(MJsonNode::MakeNumber(plusinf));
5281 n->AddToArray(MJsonNode::MakeNumber(minusinf));
5282 result = mjsonrpc_make_result("test_nan_plusinf_minusinf", n);
5283 } else if (strcmp(m, "test_arraybuffer") == 0) {
5284 if (mjsonrpc_debug) {
5285 printf("mjsonrpc: reply with test arraybuffer data\n");
5286 }
5287 size_t size = 32;
5288 char* ptr = (char*)malloc(size);
5289 assert(ptr != NULL);
5290 for (size_t i=0; i<size; i++) {
5291 ptr[i] = 'A' + i;
5292 }
5293 *((short*)(ptr+4*2*1)) = 111; // int16[4]
5294 *((int*)(ptr+4*2*2)) = 1234; // int32[4]
5295 *((double*)(ptr+4*2*3)) = 3.14; // float64[3]
5296 return MJsonNode::MakeArrayBuffer(ptr, size);
5297 } else {
5299 if (s != gMethodsTable.end()) {
5300 bool lock = s->second.fNeedsLocking;
5301 if (lock && gMutex)
5302 gMutex->lock();
5303 result = s->second.fHandler(params);
5304 if (lock && gMutex)
5305 gMutex->unlock();
5306 } else {
5307 result = mjsonrpc_make_error(-32601, "Method not found", (std::string("unknown method: ") + ms).c_str());
5308 }
5309 }
5310
5311 if (mjsonrpc_debug) {
5312 printf("mjsonrpc: handler reply:\n");
5313 result->Dump();
5314 printf("\n");
5315 }
5316
5317 double end_time = 0;
5318 double elapsed_time = 0;
5319 if (mjsonrpc_time) {
5320 end_time = GetTimeSec();
5321 elapsed_time = end_time - start_time;
5322 if (mjsonrpc_time > 1) {
5323 printf("request took %.3f seconds, method [%s]\n", elapsed_time, m);
5324 }
5325 }
5326
5327 if (result->GetType() == MJSON_ARRAYBUFFER) {
5328 return result;
5329 }
5330
5331 const MJsonNode *nerror = result->FindObjectNode("error");
5332 const MJsonNode *nresult = result->FindObjectNode("result");
5333
5334 if (nerror) {
5335 result->DeleteObjectNode("result");
5336 } else if (nresult) {
5337 result->DeleteObjectNode("error");
5338 } else {
5339 delete result;
5340 result = mjsonrpc_make_error(-32603, "Internal error", "bad dispatcher reply: no result and no error");
5341 }
5342
5343 result->AddToObject("jsonrpc", MJsonNode::MakeString("2.0"));
5344
5345 if (id) {
5346 result->AddToObject("id", id->Copy());
5347 } else {
5348 result->AddToObject("id", MJsonNode::MakeNull());
5349 }
5350
5351 if (mjsonrpc_time) {
5352 result->AddToObject("elapsed_time", MJsonNode::MakeNumber(elapsed_time));
5353 }
5354
5355 assert(result != NULL);
5356
5357 return result;
5358}
char response[10000]
Definition melog.cxx:90
char request[600000]
Definition melog.cxx:90
MethodsTable::iterator MethodsTableIterator
static double GetTimeSec()
Definition mjsonrpc.cxx:116
static MethodsTable gMethodsTable
INT add
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_make_result()

MJsonNode * mjsonrpc_make_result ( const char *  name,
MJsonNode *  value,
const char *  name2,
MJsonNode *  value2,
const char *  name3,
MJsonNode *  value3,
const char *  name4,
MJsonNode *  value4 
)

Definition at line 158 of file mjsonrpc.cxx.

159{
160 MJsonNode* node = MJsonNode::MakeObject();
161
162 if (name)
163 node->AddToObject(name, value);
164 if (name2)
165 node->AddToObject(name2, value2);
166 if (name3)
167 node->AddToObject(name3, value3);
168 if (name4)
169 node->AddToObject(name4, value4);
170
171 MJsonNode* result = MJsonNode::MakeObject();
172 result->AddToObject("result", node);
173 return result;
174}

◆ mjsonrpc_make_schema()

static MJsonNode * mjsonrpc_make_schema ( MethodsTable h)
static

Definition at line 4846 of file mjsonrpc.cxx.

4847{
4848 MJsonNode* s = MJsonNode::MakeObject();
4849
4850 s->AddToObject("$schema", MJsonNode::MakeString("http://json-schema.org/schema#"));
4851 s->AddToObject("id", MJsonNode::MakeString("MIDAS JSON-RPC autogenerated schema"));
4852 s->AddToObject("title", MJsonNode::MakeString("MIDAS JSON-RPC schema"));
4853 s->AddToObject("description", MJsonNode::MakeString("Autogenerated schema for all MIDAS JSON-RPC methods"));
4854 s->AddToObject("type", MJsonNode::MakeString("object"));
4855
4856 MJsonNode* m = MJsonNode::MakeObject();
4857
4858 for (MethodsTableIterator iterator = h->begin(); iterator != h->end(); iterator++) {
4859 // iterator->first = key
4860 // iterator->second = value
4861 //printf("build schema for method \"%s\"!\n", iterator->first.c_str());
4862 MJsonNode* doc = iterator->second.fHandler(NULL);
4863 if (doc == NULL)
4864 doc = MJsonNode::MakeObject();
4865 m->AddToObject(iterator->first.c_str(), doc);
4866 }
4867
4868 s->AddToObject("properties", m);
4869 s->AddToObject("required", MJsonNode::MakeArray());
4870
4871 return s;
4872}
Here is the caller graph for this function:

◆ mjsonrpc_schema_to_html_anything()

std::string mjsonrpc_schema_to_html_anything ( const MJsonNode *  schema,
int  nest_level,
NestedOutput o 
)
static

Definition at line 5145 of file mjsonrpc.cxx.

5146{
5147 std::string type;
5148 std::string description;
5149 //bool optional = false;
5150
5151 const MJsonNode* t = schema->FindObjectNode("type");
5152 if (t)
5153 type = t->GetString();
5154 else
5155 type = "any";
5156
5157 const MJsonNode* d = schema->FindObjectNode("description");
5158 if (d)
5159 description = d->GetString();
5160
5161 //const MJsonNode* o = schema->FindObjectNode("optional");
5162 //if (o)
5163 // optional = o->GetBool();
5164
5165 if (type == "object") {
5166 return mjsonrpc_schema_to_html_object(schema, nest_level, o);
5167 } else if (type == "array") {
5168 return mjsonrpc_schema_to_html_array(schema, nest_level, o);
5169 } else {
5170 //if (optional)
5171 // output(nest_level, false, "?");
5172 //else
5173 // output(nest_level, false, "!");
5174 o->Output(nest_level, false, type);
5175 o->Output(nest_level+1, true, description);
5176 if (description.length() > 1) {
5177 return (type + "</td><td>" + description);
5178 } else {
5179 return (type);
5180 }
5181 }
5182}
void Output(int nest, bool span, std::string text)
char description[1000]
Definition mana.cxx:267
static std::string mjsonrpc_schema_to_html_array(const MJsonNode *schema, int nest_level, NestedOutput *o)
static std::string mjsonrpc_schema_to_html_object(const MJsonNode *schema, int nest_level, NestedOutput *o)
double d
Definition system.cxx:1313
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_schema_to_html_array()

static std::string mjsonrpc_schema_to_html_array ( const MJsonNode *  schema,
int  nest_level,
NestedOutput o 
)
static

Definition at line 5089 of file mjsonrpc.cxx.

5090{
5091 const MJsonNode* d = schema->FindObjectNode("description");
5092 std::string description;
5093 if (d)
5094 description = d->GetString();
5095
5096 std::string xshort = "array";
5097 if (description.length() > 1)
5098 xshort += "</td><td>" + description;
5099
5100 const MJsonNode* items = schema->FindObjectNode("items");
5101
5102 if (!items) {
5103 o->Output(nest_level, false, "array");
5104 o->Output(nest_level+1, true, description);
5105 return xshort;
5106 }
5107
5108 const MJsonNodeVector *nodes = items->GetArray();
5109
5110 if (!nodes) {
5111 o->Output(nest_level, false, "array");
5112 o->Output(nest_level+1, true, description);
5113 return xshort;
5114 }
5115
5116 std::string nest = indent(nest_level * 4);
5117
5118 std::string s;
5119
5120 //s += "array</td><td>";
5121
5122 s += nest + "<table border=1>\n";
5123
5124 if (description.length() > 1) {
5125 s += nest + "<tr>\n";
5126 s += nest + " <td>" + description + "</td>\n";
5127 s += nest + "</tr>\n";
5128 }
5129
5130 o->Output(nest_level, true, description);
5131
5132 for (unsigned i=0; i<nodes->size(); i++) {
5133 o->Output(nest_level, false, "array of");
5134
5135 s += nest + "<tr>\n";
5136 s += nest + " <td> array of " + mjsonrpc_schema_to_html_anything((*nodes)[i], nest_level + 1, o) + "</td>\n";
5137 s += nest + "</tr>\n";
5138 }
5139
5140 s += nest + "</table>\n";
5141
5142 return s;
5143}
static std::string mjsonrpc_schema_to_html_anything(const MJsonNode *schema, int nest_level, NestedOutput *o)
static std::string indent(int x, const char *p=" ")
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mjsonrpc_schema_to_html_object()

static std::string mjsonrpc_schema_to_html_object ( const MJsonNode *  schema,
int  nest_level,
NestedOutput o 
)
static

Definition at line 5003 of file mjsonrpc.cxx.

5004{
5005 const MJsonNode* d = schema->FindObjectNode("description");
5006 std::string description;
5007 if (d)
5008 description = d->GetString();
5009
5010 std::string xshort = "object";
5011 if (description.length() > 1)
5012 xshort += "</td><td>" + description;
5013
5014 const MJsonNode* properties = schema->FindObjectNode("properties");
5015
5016 const MJsonNodeVector* required_list = NULL;
5017 const MJsonNode* r = schema->FindObjectNode("required");
5018 if (r)
5019 required_list = r->GetArray();
5020
5021 if (!properties) {
5022 o->Output(nest_level, false, "object");
5023 o->Output(nest_level+1, true, description);
5024 return xshort;
5025 }
5026
5027 const MJsonStringVector *names = properties->GetObjectNames();
5028 const MJsonNodeVector *nodes = properties->GetObjectNodes();
5029
5030 if (!names || !nodes) {
5031 o->Output(nest_level, false, "object");
5032 o->Output(nest_level+1, true, description);
5033 return xshort;
5034 }
5035
5036 std::string nest = indent(nest_level * 4);
5037
5038 std::string s;
5039
5040 s += nest + "<table border=1>\n";
5041
5042 if (description.length() > 1) {
5043 s += nest + "<tr>\n";
5044 s += nest + " <td colspan=3>" + description + "</td>\n";
5045 s += nest + "</tr>\n";
5046 }
5047
5048 o->Output(nest_level, true, description);
5049
5050 for (unsigned i=0; i<names->size(); i++) {
5051 std::string name = (*names)[i];
5052 const MJsonNode* node = (*nodes)[i];
5053
5054 bool required = false;
5055 if (required_list)
5056 for (unsigned j=0; j<required_list->size(); j++)
5057 if ((*required_list)[j])
5058 if ((*required_list)[j]->GetString() == name) {
5059 required = true;
5060 break;
5061 }
5062
5063 bool is_array = false;
5064 const MJsonNode* type = node->FindObjectNode("type");
5065 if (type && type->GetString() == "array")
5066 is_array = true;
5067
5068 if (is_array)
5069 name += "[]";
5070
5071 if (!required)
5072 name += "?";
5073
5074 o->Output(nest_level, false, name);
5075
5076 s += nest + "<tr>\n";
5077 s += nest + " <td>" + name + "</td>\n";
5078 s += nest + " <td>";
5079 s += mjsonrpc_schema_to_html_anything(node, nest_level + 1, o);
5080 s += "</td>\n";
5081 s += nest + "</tr>\n";
5082 }
5083
5084 s += nest + "</table>\n";
5085
5086 return s;
5087}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_array_index_list()

static int parse_array_index_list ( const char *  method,
const char *  path,
std::vector< unsigned > *  list 
)
static

Definition at line 557 of file mjsonrpc.cxx.

558{
559 // parse array index in form of:
560 // odbpath[number]
561 // odbpath[number,number]
562 // odbpath[number-number]
563 // or any combination of them, i.e. odbpath[1,10-15,20,30-40]
564
565 const char*s = strchr(path, '[');
566
567 if (!s) {
568 cm_msg(MERROR, method, "expected an array index character \'[\' in \"%s\"", path);
569 return DB_OUT_OF_RANGE;
570 }
571
572 s++; // skip '[' itself
573
574 while (s && (*s != 0)) {
575
576 // check that we have a number
577 if (!isdigit(*s)) {
578 cm_msg(MERROR, method, "expected a number in array index in \"%s\" at \"%s\"", path, s);
579 return DB_OUT_OF_RANGE;
580 }
581
582 unsigned value1 = strtoul(s, (char**)&s, 10);
583
584 // array range,
585 if (*s == '-') {
586 s++; // skip the minus char
587
588 if (!isdigit(*s)) {
589 cm_msg(MERROR, method, "expected a number in array index in \"%s\" at \"%s\"", path, s);
590 return DB_OUT_OF_RANGE;
591 }
592
593 unsigned value2 = strtoul(s, (char**)&s, 10);
594
595 if (value2 >= value1)
596 for (unsigned i=value1; i<=value2; i++)
597 list->push_back(i);
598 else {
599 // this is stupid. simple loop like this
600 // for (unsigned i=value1; i>=value2; i--)
601 // does not work for range 4-0, because value2 is 0,
602 // and x>=0 is always true for unsigned numbers,
603 // so we would loop forever... K.O.
604 for (unsigned i=value1; i!=value2; i--)
605 list->push_back(i);
606 list->push_back(value2);
607 }
608 } else {
609 list->push_back(value1);
610 }
611
612 if (*s == ',') {
613 s++; // skip the comma char
614 continue; // back to the begin of loop
615 }
616
617 if (*s == ']') {
618 s++; // skip the closing bracket
619 s = NULL;
620 continue; // done
621 }
622
623 cm_msg(MERROR, method, "invalid char in array index in \"%s\" at \"%s\"", path, s);
624 return DB_OUT_OF_RANGE;
625 }
626
627#if 0
628 printf("parsed array indices for \"%s\" size is %d: ", path, (int)list->size());
629 for (unsigned i=0; i<list->size(); i++)
630 printf(" %d", (*list)[i]);
631 printf("\n");
632#endif
633
634 return SUCCESS;
635}
#define DB_OUT_OF_RANGE
Definition midas.h:652
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove()

static std::string remove ( const std::string  s,
char  c 
)
static

Definition at line 253 of file mjsonrpc.cxx.

254{
255 std::string::size_type pos = s.find(c);
256 if (pos == std::string::npos)
257 return s;
258 else
259 return s.substr(0, pos);
260}
char c
Definition system.cxx:1312
Here is the caller graph for this function:

◆ set_debug()

static MJsonNode * set_debug ( const MJsonNode *  params)
static

Definition at line 4613 of file mjsonrpc.cxx.

4614{
4615 if (!params) {
4616 MJSO* doc = MJSO::I();
4617 doc->D("set new value of mjsonrpc_debug");
4618 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_debug");
4619 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_debug");
4620 return doc;
4621 }
4622
4623 mjsonrpc_debug = params->GetInt();
4624 return mjsonrpc_make_result("debug", MJsonNode::MakeInt(mjsonrpc_debug));
4625}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_sleep()

static MJsonNode * set_sleep ( const MJsonNode *  params)
static

Definition at line 4640 of file mjsonrpc.cxx.

4641{
4642 if (!params) {
4643 MJSO* doc = MJSO::I();
4644 doc->D("set new value of mjsonrpc_sleep");
4645 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_sleep");
4646 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_sleep");
4647 return doc;
4648 }
4649
4650 mjsonrpc_sleep = params->GetInt();
4651 return mjsonrpc_make_result("sleep", MJsonNode::MakeInt(mjsonrpc_sleep));
4652}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_time()

static MJsonNode * set_time ( const MJsonNode *  params)
static

Definition at line 4667 of file mjsonrpc.cxx.

4668{
4669 if (!params) {
4670 MJSO* doc = MJSO::I();
4671 doc->D("set new value of mjsonrpc_time");
4672 doc->P(NULL, MJSON_INT, "new value of mjsonrpc_time");
4673 doc->R(NULL, MJSON_INT, "new value of mjsonrpc_time");
4674 return doc;
4675 }
4676
4677 mjsonrpc_time = params->GetInt();
4678 return mjsonrpc_make_result("time", MJsonNode::MakeInt(mjsonrpc_time));
4679}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_program()

static MJsonNode * start_program ( const MJsonNode *  params)
static

Definition at line 483 of file mjsonrpc.cxx.

484{
485 if (!params) {
486 MJSO* doc = MJSO::I();
487 doc->D("start MIDAS program defined in ODB /Programs/name");
488 doc->P("name", MJSON_STRING, "name of the program, corresponding to ODB /Programs/name");
489 doc->R("status", MJSON_INT, "return status of ss_system()");
490 return doc;
491 }
492
493 MJsonNode* error = NULL;
494
495 std::string name = mjsonrpc_get_param(params, "name", &error)->GetString(); if (error) return error;
496
497 std::string path = "";
498 path += "/Programs/";
499 path += name;
500 path += "/Start command";
501
502 HNDLE hDB;
504
505 std::string command;
506 int status = db_get_value_string(hDB, 0, path.c_str(), 0, &command);
507
508 if (status == DB_SUCCESS && command.length() > 0) {
509 //printf("ss_system(\"%s\")\n", command.c_str());
510 status = ss_system(command.c_str());
511 }
512
513 return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
514}
INT ss_system(const char *command)
Definition system.cxx:2188
Here is the call graph for this function:
Here is the caller graph for this function:

◆ StashEvent()

static void StashEvent ( const std::string  buffer_name,
int  event_id,
int  trigger_mask,
const EVENT_HEADER pevent 
)
static

Definition at line 3688 of file mjsonrpc.cxx.

3689{
3690 std::lock_guard<std::mutex> guard(gEventStashMutex);
3691 bool found = false;
3692 for (EventStashEntry* s : gEventStash) {
3693 if (s->buffer_name != buffer_name)
3694 continue;
3695 if (s->event_id == event_id && s->trigger_mask == trigger_mask) {
3696 found = true;
3697 s->ReplaceEvent(pevent);
3698 //s->Print(); printf(", replaced\n");
3699 } else if (bm_match_event(s->event_id, s->trigger_mask, pevent)) {
3700 s->ReplaceEvent(pevent);
3701 //s->Print(); printf(", matched\n");
3702 }
3703 }
3704 if (!found) {
3707 s->event_id = event_id;
3709 s->pevent = CopyEvent(pevent);
3710 //s->Print(); printf(", added\n");
3711 gEventStash.push_back(s);
3712 }
3713}
std::string buffer_name
int event_id
const EVENT_HEADER * pevent
int trigger_mask
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xnull()

static MJsonNode * xnull ( const MJsonNode *  params)
static

Definition at line 413 of file mjsonrpc.cxx.

414{
415 if (!params) {
416 MJSO* doc = MJSO::I();
417 doc->D("RPC method always returns null");
418 doc->P(NULL, 0, "method parameters are ignored");
419 doc->R(NULL, MJSON_NULL, "always returns null");
420 return doc;
421 }
422
423 return mjsonrpc_make_result(MJsonNode::MakeNull());
424}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ gEventStash

std::vector<EventStashEntry*> gEventStash
static

Definition at line 3686 of file mjsonrpc.cxx.

◆ gEventStashMutex

std::mutex gEventStashMutex
static

Definition at line 3685 of file mjsonrpc.cxx.

◆ gHistoryChannels

MhiMap gHistoryChannels
static

Definition at line 1684 of file mjsonrpc.cxx.

◆ gMethodsTable

MethodsTable gMethodsTable
static

Definition at line 4732 of file mjsonrpc.cxx.

◆ gMutex

std::mutex* gMutex = NULL
static

Definition at line 4733 of file mjsonrpc.cxx.

◆ gNullNode

MJsonNode* gNullNode = NULL
static

Definition at line 176 of file mjsonrpc.cxx.

◆ mjsonrpc_sleep

int mjsonrpc_sleep = 0
static

Definition at line 113 of file mjsonrpc.cxx.

◆ mjsonrpc_time

int mjsonrpc_time = 0
static

Definition at line 114 of file mjsonrpc.cxx.