1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
16 #include "../core/Logger.hh"
18 using mctr::MainController
;
19 using namespace jnimw
;
21 Jnimw
*Jnimw::userInterface
;
22 bool Jnimw::has_status_message_pending
;
26 * The last MC state. It is needed by status_change(), as
27 * status change message is written to the pipe when any status (MC, TC, HC) was changed AND
28 * ( currently there is no status change message on the pipe (signalled by has_status_message_pending)
29 * OR MC state is changed )
31 mctr::mc_state_enum last_mc_state
;
33 pthread_mutex_t
Jnimw::mutex
= PTHREAD_MUTEX_INITIALIZER
;
36 * Config data, which was created by Java_org_eclipse_titan_executor_jni_JNIMiddleWare_set_1cfg_1file()
37 * by a JNI request, and the result will be used by
38 * Java_org_eclipse_titan_executor_jni_JNIMiddleWare_configure().
39 * This is done this way to use process_config_read_file() for processing the config file
40 * instead of processing it on the Java side.
42 config_data
Jnimw::mycfg
;
46 int result
= pthread_mutex_lock(&mutex
);
48 fatal_error("Jni middleware::lock: "
49 "pthread_mutex_lock failed with code %d.", result
);
55 int result
= pthread_mutex_unlock(&mutex
);
57 fatal_error("Jni middleware:::unlock: "
58 "pthread_mutex_unlock failed with code %d.", result
);
62 void Jnimw::fatal_error(const char *fmt
, ...)
66 vfprintf(stderr
, fmt
, ap
);
68 if (errno
!= 0) fprintf(stderr
, " (%s)", strerror(errno
));
73 int Jnimw::enterLoop(int, char*[]) {
85 FD_SET(pipe_fd
[0], &readfds
);
87 has_status_message_pending
= false;
88 last_mc_state
= mctr::MC_INACTIVE
;
91 if (pthread_mutex_init(&mutex
, NULL
))
92 fatal_error("Jni middleware::constructor: pthread_mutex_init failed.");
99 pthread_mutex_destroy(&mutex
);
103 void strreverse(char* begin
, char* end
) {
106 aux
=*end
, *end
--=*begin
, *begin
++=aux
;
111 * Ansi C "itoa" based on Kernighan & Ritchie's "Ansi C":
113 void itoa(int value
, char* str
) {
114 static char num
[] = "0123456789";
117 // Conversion. Number is reversed.
118 do *wstr
++ = num
[value
%10]; while(value
/=10);
122 strreverse(str
,wstr
-1);
125 void create_packet_header(const int source_length
, char* dest
, char method_id
) {
128 itoa(source_length
, packet_size
);
130 for(i
= 1; i
< 6; i
++) dest
[i
] = '0';
132 int j
= strlen(packet_size
);
133 for(i
= 0; i
< j
; i
++) dest
[5-i
] = packet_size
[j
-i
-1];
136 char* stuffer(const char* msg
){
137 char* msg_stuffed
= (char*) malloc(strlen(msg
)*2);
140 while(msg
[i
] != '\0') {
141 if(msg
[i
] != '|' && msg
[i
] != '\\') {
142 msg_stuffed
[j
++] = msg
[i
];
144 msg_stuffed
[j
++] = '\\';
145 msg_stuffed
[j
++] = msg
[i
];
149 msg_stuffed
[j
] = '\0';
154 //----------------------------------------------------------------------------
157 void Jnimw::status_change()
160 mctr::mc_state_enum mc_state
= MainController::get_state();
161 if(last_mc_state
!= mc_state
|| !has_status_message_pending
){
163 sprintf( str
,"S%02d000", mc_state
);
166 has_status_message_pending
= true;
167 last_mc_state
= mc_state
;
171 //----------------------------------------------------------------------------
174 void Jnimw::error(int severity
, const char* msg
)
176 char *msg_stuffed
= stuffer(msg
);
179 // creating packet header
180 char packet_header
[7];
182 tmp
= mprintf("%d|%s", severity
, msg_stuffed
);
183 create_packet_header(strlen(tmp
), packet_header
, 'E');
185 pipe_s
= mprintf("%s%s", packet_header
, tmp
);
191 //----------------------------------------------------------------------------
194 void Jnimw::notify(const struct timeval
* time
, const char* source
,
195 int severity
, const char* msg
)
197 char *source_stuffed
= stuffer(source
);
198 char *msg_stuffed
= stuffer(msg
);
201 // creating packet header
202 char packet_header
[7];
204 tmp
= mprintf("%ld|%ld|%s|%d|%s", time
->tv_sec
, time
->tv_usec
, source_stuffed
, severity
, msg_stuffed
);
205 create_packet_header(strlen(tmp
), packet_header
, 'N');
207 pipe_s
= mprintf("%s%s", packet_header
, tmp
);
209 free(source_stuffed
);
215 void Jnimw::create_pipe()
218 printf("Jnimw::create_pipes(): pipe system call failed.\n");
222 void Jnimw::destroy_pipe()
230 bool Jnimw::is_pipe_readable(){
231 // TODO maybe this could get faster
237 FD_SET(pipe_fd
[0], &read_set
);
238 int ret
= select(pipe_fd
[0] + 1 , &read_set
, NULL
, NULL
, &time
);
242 char* Jnimw::read_pipe()
244 select(pipe_fd
[0] + 1 , &readfds
, NULL
, NULL
, NULL
);
247 pipe_buffer
= (char*)malloc(7);
248 int ret
= read(pipe_fd
[0], pipe_buffer
, 6);
250 printf("Malformed packet arrived!\n");
255 if(pipe_buffer
[0] == 'S'){
256 has_status_message_pending
= false;
262 int packet_size
= (pipe_buffer
[1]-48) * 10000 + (pipe_buffer
[2]-48) * 1000 +
263 (pipe_buffer
[3]-48) * 100 + (pipe_buffer
[4]-48) * 10 + (pipe_buffer
[5]-48);
265 pipe_buffer
= (char*)realloc(pipe_buffer
, packet_size
+ 7);
267 ret
= read(pipe_fd
[0],pipe_buffer
+ 6, packet_size
);
268 if(ret
!= packet_size
){
269 printf("Jnimw::read_pipe(): read system call failed\n");
271 pipe_buffer
[packet_size
+ 6] = '\0';
279 void Jnimw::write_pipe(const char *buf
)
281 if (write(pipe_fd
[1], buf
, strlen(buf
)) < 0){
282 printf("Jnimw::write_pipe(): write system call failed\n");
285 pipe_size
+=strlen(buf
);