]> git.cworth.org Git - vogl/blob - src/voglreplay/vogl_remote.cpp
Initial vogl checkin
[vogl] / src / voglreplay / vogl_remote.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #if VOGL_REMOTING
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <time.h>
34
35 #include <pthread.h>
36
37 #include "../common/radlogging.h"
38 #include "../common/channel.h"
39
40 #include "../public/rpcec.h"
41 #include "../public/rpcconst.h"
42
43 #include "vogl_console.h"
44
45 #include "vogl_remote.h"
46
47 #include "debugserver.pb.h"
48 #include "gpureplaycontrol.pb.h"
49
50 // Needs to be the same in the server gpusession code
51 #define REQRESP_PORT 5600
52 #define LOGSTREAM_PORT (REQRESP_PORT + 1)
53
54 void *InvokeGLIReplayListener(void *arg);
55
56 static bool g_ping_value; //  Just for testing aliveness...
57
58 void vogl_init_listener()
59 {
60     pthread_t threadCmd;
61     int err = 0;
62     syslog(RAD_INFO, "Spinning up listener for GLI Replayer...\n");
63
64     //  Launching a GLI Listener
65     err = pthread_create(&threadCmd, NULL, InvokeGLIReplayListener, NULL);
66     if (0 != err)
67     {
68         syslog(RAD_ERROR, "Unable to create GLI Replayer cmd thread. returned %d, errno %d\n", err, errno);
69         return;
70     }
71
72     return;
73 }
74
75 bool ProcessCommandGLIReplay(std::string strReq, std::string *pstrResp);
76 RPCEC rpcecFromChec(network::CHEC chec);
77
78 #define MAX_RETRIES 10
79 #define NET_TIMEOUT 500 // MS
80
81 void *
82 InvokeGLIReplayListener(void * /*arg*/) // arg is unused
83 {
84     //
85     //  Setup to wait for a client to connect
86     //
87     pthread_t thisThread = pthread_self();
88     RPCEC rpcec = rpcecNone;
89     bool fKeepRunning = true;
90     network::CHEC chec = network::EC_NONE;
91
92     int port = REQRESP_PORT;
93
94     g_ping_value = false; //  Just for testing aliveness...
95
96     while (fKeepRunning)
97     {
98         network::channel *pChannel = NULL;
99
100         pChannel = new network::channel();
101         if (NULL == pChannel)
102         {
103             syslog(RAD_ERROR, "%lx: InvokeGLIReplayListener: Error allocating channel object: OOM\n", thisThread);
104             goto out;
105         }
106
107         chec = pChannel->Connect(port, 3, true);
108         if (network::EC_NONE != chec)
109         {
110             syslog(RAD_ERROR, "%lx: InvokeGLIReplayListener: Error on ChannelConnect(port = %d, errno = %x): %x\nTerminating...\n", thisThread, port, errno, chec);
111             goto out;
112         }
113
114         std::string strReq;
115         std::string strResp;
116
117         chec = pChannel->ReadMsg(&strReq, 1, 0);
118         rpcec = rpcecFromChec(chec);
119         if (rpcecNone != rpcec)
120         {
121             goto out;
122         }
123
124         fKeepRunning = ProcessCommandGLIReplay(strReq, &strResp);
125
126         chec = pChannel->WriteMsg(strResp, 1, 0);
127         rpcec = rpcecFromChec(chec);
128         if (rpcecNone != rpcec)
129         {
130             goto out;
131         }
132
133         pChannel->Disconnect();
134         delete pChannel;
135     }
136
137 out:
138     syslog(RAD_INFO, "%lx: GLI Replayer server thread: Terminating.\n", thisThread);
139
140     return NULL;
141 }
142
143 RPCEC PingPB(int sessionid, std::string strReq, std::string *pstrResp, int *perrno, std::string *pstrError);
144 //RPCEC RegisterLogCallbackPB(int sessionid, std::string strReq, std::string *pstrResp, int *perrno, std::string *pstrError);
145 //RPCEC DeregisterLogCallbackPB(int sessionid, std::string strReq, std::string *pstrResp, int *perrno, std::string *pstrError);
146
147 bool
148 ProcessCommandGLIReplay(std::string strReq, std::string *pstrResp)
149 {
150     bool fKeepRunning = true;
151     RPCEC rpcec = rpcecNone;
152     std::string strReqInner;
153     std::string strRespInner;
154     int err = 0;
155     std::string strError;
156
157     debugserverpb::BaseMethodReqPB gpuBaseReq;
158     debugserverpb::BaseMethodRespPB gpuBaseResp;
159
160     int interfaceid;
161     int method;
162
163     gpuBaseReq.ParseFromString(strReq);
164
165     interfaceid = gpuBaseReq.interfaceid();
166     method = gpuBaseReq.method();
167     strReqInner = gpuBaseReq.embeddedrequest();
168
169     //  Should never happen...
170     if (GLIREPLAYCONTROL != interfaceid)
171     {
172         // Currently only a single interface is known for GLI.  If it's not this one, not sure what's supposed to happen.
173         syslog(RAD_ERROR, "ProcessCommandGLIReplay: GPUReplayerControl: Unknown interfaceid (%d) passed to vogltrace from client\n", interfaceid);
174         strError = "ProcessCommandGLIReplay: GPUReplayerControl: Unknown interfaceid passed to voglreplayer from client";
175         rpcec = rpcecFail;
176         goto out;
177     }
178
179     switch (method)
180     {
181
182         case gpureplaycontrolpb::PING:
183         {
184             rpcec = PingPB(gpuBaseReq.dbgsessionid(), strReqInner, &strRespInner, &err, &strError);
185
186             if (rpcecNone != rpcec)
187             {
188                 syslog(RAD_ERROR, "ProcessCommandGLIReplay: GPUReplayerControl: Ping() failed\n");
189             }
190
191             break;
192         }
193 #ifdef NOTYET
194         case gpucontrolpb::REGISTERLOGCALLBACK:
195         {
196             rpcec = RegisterLogCallbackPB(gpuBaseReq.dbgsessionid(), strReqInner, &strRespInner, &err, &strError);
197
198             if (rpcecNone != rpcec)
199             {
200                 syslog(RAD_ERROR, "ProcessCommandGLIReplay: GPUReplayerControl: RegisterLogCallback() failed\n");
201             }
202
203             break;
204         }
205
206         case gpucontrolpb::DEREGISTERLOGCALLBACK:
207         {
208             rpcec = DeregisterLogCallbackPB(gpuBaseReq.dbgsessionid(), strReqInner, &strRespInner, &err, &strError);
209
210             if (rpcecNone != rpcec)
211             {
212                 syslog(RAD_ERROR, "ProcessCommandGLIReplay: GPUReplayerControl: DeregisterLogCallback() failed\n");
213             }
214
215             break;
216         }
217
218 #endif // NOTYET
219
220         default:
221         {
222             syslog(RAD_ERROR, "ProcessCommandGLIReplay: Unknown method (%d) for GPUReplayerControl interface\n", method);
223             strError = "ProcessCommandGLIReplay: GPUReplayerControl: Unknown method passed to vogltrace interface from client";
224             rpcec = rpcecFail;
225             break;
226         }
227     }
228
229 out:
230     //  Set the method back into the response
231     //
232     gpuBaseResp.set_interfaceid(interfaceid);
233     gpuBaseResp.set_method(method);
234     gpuBaseResp.set_rpcec(rpcec);
235     if (rpcecNone != rpcec)
236     {
237         syslog(RAD_ERROR, "ProcessCommandGLIReplay: GPUReplayerControl: returning errors to client (rpcec = %d)\n", rpcec);
238         gpuBaseResp.set_errorstring(strError);
239         gpuBaseResp.set_lowlevelerror(err);
240     }
241
242     gpuBaseResp.set_embeddedresponse(strRespInner);
243
244     gpuBaseResp.SerializeToString(pstrResp);
245
246     return fKeepRunning;
247 }
248
249 //
250 //  PingPB
251 //
252 //  Parameters:
253 //    sessionid - unused here, but the intent is that if there's any state associated with this particular request that needs to be maintained serverside
254 //                                that this could be used to indicate which of potentially many sets of these states should be used.  Feel free to ignore if not needed.
255 //        strReq    - a serialized protobuf string (std::string) that contains the parameters to the request.  The idea is that you would ParseFromString this
256 //                                parameter into your request structure (defined in your .proto file) and then pull parameters as needed.
257 //    strResp   - a serialized protobuf string (std::string) that contains the response data from this request.  The idea is that you would set all the response
258 //                            values into your response protobuf (defined in your .proto file) and then serialize that structure to a std::string and return it from here.
259 //    perrno    - this is any service specific error number that might need to be returned as part of this specific method/interface.
260 //    pstrError - along with perrno, there may be a human-readable string that can be returned.  This is where you might return it.
261 //
262 //  Returns:
263 //        RPCEC     - if all goes well with parsing and generating the protobufs or any network related stuff, then this should be rpcecNone.  Otherwise if there's a
264 //                                a problem with these areas, then an appropriate RPCEC error should be returned here (see rpcec.h).
265 //
266 RPCEC PingPB(int /*sessionid*/, std::string strReq, std::string *pstrResp, int * /*perrno*/, std::string * /*pstrError*/)
267 {
268     RPCEC rpcec = rpcecNone;
269     gpureplaycontrolpb::PingReqPB gpuPingReq;
270     gpureplaycontrolpb::PingRespPB gpuPingResp;
271
272     bool ping = false;
273
274     gpuPingReq.ParseFromString(strReq);
275
276     ping = gpuPingReq.ping();
277
278     if (ping == g_ping_value)
279         gpuPingResp.set_message((ping ? "Same ping value as last time: TRUE" : "Same ping value as last time: FALSE"));
280     else
281         gpuPingResp.set_message((ping ? "Different ping value as last time: FALSE->TRUE" : "Different ping value as last time: TRUE->FALSE"));
282
283     g_ping_value = ping;
284
285     gpuPingResp.SerializeToString(pstrResp);
286
287     return rpcec;
288 }
289
290 #ifdef NOTYET
291 //
292 //  Log Callback Globals
293 static bool g_fLogCallbackEnabled = false;
294 static int g_cRegisteredCallbacks = 0;
295 static int g_logCallbackPort = LOGSTREAM_PORT;
296 static network::channel *g_pChannelLogCallBack = NULL;
297
298 void *InvokeLogListener(void *arg);
299 bool log_output_func(vogl::eConsoleMessageType type, const char *pMsg, void *pData);
300
301 typedef struct _regtype
302 {
303     int sessionid;
304     int registration;
305     int maxpacketsize;
306     LOGTYPE ltFilter;
307 } REGTYPE;
308
309 static REGTYPE g_registrations[MAX_REGISTRATIONS] = { { SESSIONID_NONE, 0, 0, LT_INVALID } };
310
311 //
312 //  RegisterLogCallbackPB
313 //
314 //  Parameters:
315 //    sessionid - unused here, but the intent is that if there's any state associated with this particular request that needs to be maintained serverside
316 //                                that this could be used to indicate which of potentially many sets of these states should be used.  Feel free to ignore if not needed.
317 //        strReq    - a serialized protobuf string (std::string) that contains the parameters to the request.  The idea is that you would ParseFromString this
318 //                                parameter into your request structure (defined in your .proto file) and then pull parameters as needed.
319 //    strResp   - a serialized protobuf string (std::string) that contains the response data from this request.  The idea is that you would set all the response
320 //                            values into your response protobuf (defined in your .proto file) and then serialize that structure to a std::string and return it from here.
321 //    perrno    - this is any service specific error number that might need to be returned as part of this specific method/interface.
322 //    pstrError - along with perrno, there may be a human-readable string that can be returned.  This is where you might return it.
323 //
324 //  Returns:
325 //        RPCEC     - if all goes well with parsing and generating the protobufs or any network related stuff, then this should be rpcecNone.  Otherwise if there's a
326 //                                a problem with these areas, then an appropriate RPCEC error should be returned here (see rpcec.h).
327 //
328 RPCEC RegisterLogCallbackPB(int /*sessionid*/, std::string strReq, std::string *pstrResp, int *perrno, std::string *pstrError)
329 {
330
331     //  Registering and Deregistering these logging callbacks always happen on the same thread.  So any global that only these two functions use will be safe
332     //  to use.
333
334     RPCEC rpcec = rpcecNone;
335     gpucontrolpb::RegisterLogCallbackReqPB gpuRegisterLogCallbackReq;
336     gpucontrolpb::RegisterLogCallbackRespPB gpuRegisterLogCallbackResp;
337
338     LOGTYPE ltReq = LT_INVALID;
339     int registrationid = REGISTRATION_INVALID; // Invalid
340     int registrationindex = MAX_REGISTRATIONS + 1;
341
342     //
343     //
344     gpuRegisterLogCallbackReq.ParseFromString(strReq);
345
346     //
347     //  Register log callback
348     //  typedef bool (*console_output_func)(eConsoleMessageType type, const char* pMsg, void* pData);
349     //  vogl::console::add_console_output_func(LogCallbackFunc, NULL);
350
351     ltReq = (LOGTYPE)gpuRegisterLogCallbackReq.logfilter();
352     if (LT_INVALID == ltReq)
353     {
354         syslog(RAD_ERROR, "GLI RegisterLogCallbackPB - invalid log filter (LT_INVALID) requested\n");
355         rpcec = rpcecFail;
356         *pstrError = "GLI RegisterLogCallbackPB - invalid log filter (LT_INVALID) requested";
357         *perrno = 0;
358
359         goto out;
360     }
361
362     //
363     //  Find the next available slot to register our filter for this registration
364     for (int i = 0; i < MAX_REGISTRATIONS; i++)
365     {
366         if (LT_INVALID == g_registrations[i].ltFilter)
367         {
368             registrationid = rand() + 1; //  Not really random enough...
369             registrationindex = i;
370             break;
371         }
372     }
373
374     if (MAX_REGISTRATIONS + 1 == registrationindex)
375     {
376         //  Too many registrations!
377         rpcec = rpcecFail;
378         *pstrError = "GLI RegisterLogCallbackPB - too many registrations already.  Deregister some and try again.";
379         *perrno = 0;
380
381         goto out;
382     }
383
384     //  Check to see if we need a connection
385     //
386     if (!g_fLogCallbackEnabled)
387     {
388         //  Spawn a thread to be connected to
389         pthread_t threadLogging;
390         int err = 0;
391         syslog(RAD_INFO, "Spinning up thread for GLI Trace logging...\n");
392
393         //  Launching a GLI Listener
394         err = pthread_create(&threadLogging, NULL, InvokeLogListener, NULL); // &port??
395         if (0 != err)
396         {
397             syslog(RAD_ERROR, "Unable to create GLI Logging thread. returned %d, errno %d\n", err, errno);
398             rpcec = rpcecFail;
399             *pstrError = "GLI RegisterLogCallbackPB - Unable to create GLI Logging thread.  See system log for more info.";
400             *perrno = errno;
401             goto out;
402         }
403         //
404         //  Register log callback - we only have one of these and we get rid of it when
405         //  we have no more registrations.
406         //
407         //      typedef bool (*console_output_func)(eConsoleMessageType type, const char* pMsg, void* pData);
408         //      vogl::console::add_console_output_func(LogCallbackFunc, NULL);
409         vogl::console::add_console_output_func(log_output_func, NULL);
410     }
411
412     g_registrations[registrationindex].ltFilter = ltReq;
413     g_registrations[registrationindex].registration = registrationid;
414     g_cRegisteredCallbacks++;
415
416     gpuRegisterLogCallbackResp.set_registrationid(registrationid);
417
418 out:
419     gpuRegisterLogCallbackResp.SerializeToString(pstrResp);
420
421     return rpcec;
422 }
423
424 //
425 //  DeregisterLogCallbackPB
426 //
427 //  Parameters:
428 //    sessionid - unused here, but the intent is that if there's any state associated with this particular request that needs to be maintained serverside
429 //                                that this could be used to indicate which of potentially many sets of these states should be used.  Feel free to ignore if not needed.
430 //        strReq    - a serialized protobuf string (std::string) that contains the parameters to the request.  The idea is that you would ParseFromString this
431 //                                parameter into your request structure (defined in your .proto file) and then pull parameters as needed.
432 //    strResp   - a serialized protobuf string (std::string) that contains the response data from this request.  The idea is that you would set all the response
433 //                            values into your response protobuf (defined in your .proto file) and then serialize that structure to a std::string and return it from here.
434 //    perrno    - this is any service specific error number that might need to be returned as part of this specific method/interface.
435 //    pstrError - along with perrno, there may be a human-readable string that can be returned.  This is where you might return it.
436 //
437 //  Returns:
438 //        RPCEC     - if all goes well with parsing and generating the protobufs or any network related stuff, then this should be rpcecNone.  Otherwise if there's a
439 //                                a problem with these areas, then an appropriate RPCEC error should be returned here (see rpcec.h).
440 //
441 RPCEC DeregisterLogCallbackPB(int /*sessionid*/, std::string strReq, std::string *pstrResp, int *perrno, std::string *pstrError)
442 {
443     RPCEC rpcec = rpcecNone;
444     int registrationid = REGISTRATION_INVALID; // Invalid
445     int registrationindex = MAX_REGISTRATIONS + 1;
446
447     gpucontrolpb::DeregisterLogCallbackReqPB gpuDeregisterLogCallbackReq;
448     gpucontrolpb::DeregisterLogCallbackRespPB gpuDeregisterLogCallbackResp;
449
450     gpuDeregisterLogCallbackReq.ParseFromString(strReq);
451
452     registrationid = gpuDeregisterLogCallbackReq.registrationid();
453
454     //
455     //  Find the registrationid in the list
456     //
457     for (int i = 0; i < MAX_REGISTRATIONS; i++)
458     {
459         if (registrationid == g_registrations[i].registration)
460         {
461             registrationindex = i;
462             break;
463         }
464     }
465
466     if (MAX_REGISTRATIONS <= registrationindex)
467     {
468         //  Out of bounds
469         rpcec = rpcecFail;
470         *pstrError = "GLI DeregisterLogCallbackPB - Unknown registration id(1).";
471         *perrno = 0;
472
473         goto out;
474     }
475
476     if (LT_INVALID == g_registrations[registrationindex].ltFilter)
477     {
478         //  Invalid registrationid
479         rpcec = rpcecFail;
480         *pstrError = "GLI DeregisterLogCallbackPB - Unknown registration id(2).";
481         *perrno = 0;
482         goto out;
483     }
484
485     g_registrations[registrationindex].ltFilter = LT_INVALID;
486     g_registrations[registrationindex].registration = REGISTRATION_INVALID;
487
488     g_cRegisteredCallbacks--;
489     if (0 == g_cRegisteredCallbacks)
490     {
491         vogl::console::remove_console_output_func(log_output_func);
492         g_fLogCallbackEnabled = false;
493         // Race condition?  We could be sending a log on a different thread and then try to close out socket and descroy the context here at
494         // the same time.
495         //
496         g_pChannelLogCallBack->Disconnect();
497         delete g_pChannelLogCallBack;
498         g_pChannelLogCallBack = NULL;
499     }
500
501 out:
502     gpuDeregisterLogCallbackResp.SerializeToString(pstrResp);
503
504     return rpcec;
505 }
506
507 void *
508 InvokeLogListener(void * /*arg*/)
509 {
510     //
511     //  Setup to wait for a client to connect
512     //
513     pthread_t thisThread = pthread_self();
514     network::CHEC chec = network::EC_NONE;
515
516     g_pChannelLogCallBack = new network::channel();
517
518     chec = g_pChannelLogCallBack->Connect(g_logCallbackPort, 3, true);
519     if (network::EC_NONE != chec)
520     {
521         g_pChannelLogCallBack->Disconnect();
522         delete g_pChannelLogCallBack;
523         g_pChannelLogCallBack = NULL;
524
525         syslog(RAD_ERROR, "%lx: InvokeLogListener: Error on pChannel::Connect(port = %d, errno = %x): %x\nTerminating...\n", thisThread, g_logCallbackPort, errno, chec);
526         goto out;
527     }
528
529     g_fLogCallbackEnabled = true;
530
531 out:
532     return NULL;
533 }
534
535 LOGTYPE crnMsgTypeToLogType(vogl::eConsoleMessageType type);
536 RPCEC EcSendNotif(network::channel *pChannel, int notifid, int sessionid, std::string strLogMsg);
537
538 bool log_output_func(vogl::eConsoleMessageType type, const char *pMsg, void * /*pData*/)
539 {
540     //  NOTE:  This could be called from any thread...  We're not 100% safe.
541     pthread_t thisThread = pthread_self();
542     LOGTYPE ltMessage = LT_INVALID;
543     RPCEC rpcec = rpcecNone;
544
545     gpucontrolpb::LogCallbackPB logMessagePB;
546     std::string strLogMsg;
547
548     bool fFoundAtLeastOneMatch = false;
549     int registrationid = REGISTRATION_INVALID;
550
551     if (!g_fLogCallbackEnabled)
552     {
553         //  No one is ready to receive this data.  Dump the pMsg.
554
555         goto out;
556     }
557
558     //  Filter out those messages that we're not looking for
559     ltMessage = crnMsgTypeToLogType(type);
560
561     // Loop through all our registrations and for those that are interested in
562     // this message, add them to the list of registrations this matches
563     //
564     for (int i = 0; i < MAX_REGISTRATIONS; i++)
565     {
566         if ((ltMessage & g_registrations[i].ltFilter))
567         {
568             if (REGISTRATION_INVALID != g_registrations[i].registration)
569             {
570                 fFoundAtLeastOneMatch = true;
571
572                 registrationid = g_registrations[i].registration;
573
574                 logMessagePB.add_sessionids(g_registrations[i].sessionid);
575                 logMessagePB.add_registrationids(registrationid);
576             }
577         }
578     }
579
580     if (!fFoundAtLeastOneMatch)
581     {
582         //  Nothing matches the filter...drop the pMsg.
583
584         goto out;
585     }
586
587     logMessagePB.set_logtype(ltMessage);
588
589     logMessagePB.set_message(pMsg);
590
591     logMessagePB.SerializeToString(&strLogMsg);
592
593     //
594     //  Actually send it
595     //
596     //  We have a list of sessionids in the actual message...no need to choose one here.
597     rpcec = EcSendNotif(g_pChannelLogCallBack, gpucontrolpb::LOGCALLBACK, SESSIONID_NONE, strLogMsg);
598
599     if (rpcecNone != rpcec)
600     {
601         syslog(RAD_ERROR, "%lx: log_output_func(id=%d) EcSendResponse returns %x.  Message \"%s\" unsent.\n", thisThread, registrationid, rpcec, pMsg);
602         goto out;
603     }
604
605 out:
606
607     return true;
608 }
609
610 RPCEC EcSendNotif(network::channel *pChannel, int notifid, int sessionid, std::string strLogMsg)
611 {
612     RPCEC rpcec = rpcecNone;
613     //  Wraps the strLogMsg in the appropriate
614     debugserverpb::BaseMethodNotifPB gpuNotifPB;
615     std::string strNotifMsg;
616
617     gpuNotifPB.set_notifid(notifid);
618     gpuNotifPB.set_dbgsessionid(sessionid);
619
620     gpuNotifPB.set_embeddednotif(strLogMsg);
621
622     gpuNotifPB.SerializeToString(&strNotifMsg);
623
624     rpcec = EcSendResponse(pChannel, strNotifMsg);
625
626     return rpcec;
627 }
628
629 LOGTYPE crnMsgTypeToLogType(vogl::eConsoleMessageType type)
630 {
631
632     switch (type)
633     {
634         case vogl::cDebugConsoleMessage:
635         {
636             return LT_DEBUG;
637         }
638         case vogl::cProgressConsoleMessage:
639         {
640             return LT_PROGRESS;
641         }
642         case vogl::cInfoConsoleMessage:
643         {
644             return LT_INFO;
645         }
646         case vogl::cConsoleConsoleMessage:
647         {
648             return LT_DEFAULT;
649         }
650         case vogl::cMessageConsoleMessage:
651         {
652             return LT_MESSAGE;
653         }
654         case vogl::cWarningConsoleMessage:
655         {
656             return LT_WARNING;
657         }
658         case vogl::cErrorConsoleMessage:
659         {
660             return LT_ERROR;
661         }
662         default:
663         {
664             break;
665         }
666     }
667
668     return LT_LOG; // Not sure what else to do here...?
669 }
670 #endif // NOTYET
671
672 RPCEC
673 rpcecFromChec(network::CHEC chec)
674 {
675     switch (chec)
676     {
677         case network::EC_NONE:
678         {
679             return rpcecNone;
680         }
681         case network::EC_TIMEOUT:
682         {
683             return rpcecTimeout;
684         }
685         case network::EC_NETWORK:
686         {
687             return rpcecFail;
688         }
689         case network::EC_MEMORY:
690         {
691             return rpcecFail;
692         }
693         default:
694         {
695             return rpcecFail;
696         }
697     }
698
699     return rpcecFail;
700 }
701 #endif // VOGL_REMOTING