| /******************************************************************************* | |
| * Copyright (c) 2010 Nokia and others. | |
| * All rights reserved. This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License v1.0 | |
| * which accompanies this distribution, and is available at | |
| * http://www.eclipse.org/legal/epl-v10.html | |
| * | |
| * Contributors: | |
| * Nokia - Initial API and implementation | |
| *******************************************************************************/ | |
| #include "EventClientNotifier.h" | |
| #include "TCFHeaders.h" | |
| #include "Logger.h" | |
| #include "AgentUtils.h" | |
| #include "TCFOutputStream.h" | |
| #include "ProtocolConstants.h" | |
| #include "ThreadContext.h" | |
| #include "ContextManager.h" | |
| extern void debug_session_ends(); | |
| TCFBroadcastGroup * EventClientNotifier::broadcastGroup = NULL; | |
| static const char RUN_CONTROL[] = "RunControl"; | |
| SendRemovedEventParams::SendRemovedEventParams(Context* context_, bool delete_) { | |
| context = context_; | |
| deleteContext = delete_; | |
| } | |
| SendExeEventParams::SendExeEventParams(Context* context_, unsigned long pcAddress_, const Properties& properties_) { | |
| context = context_; | |
| properties = properties_; | |
| pcAddress = pcAddress_; | |
| } | |
| SendExceptionEventParams::SendExceptionEventParams(Context* context_, | |
| const std::string& description_) { | |
| context = context_; | |
| description = description_; | |
| } | |
| SendSuspendEventParams::SendSuspendEventParams(Context* context_, unsigned long pcAddress_, | |
| const char* reason_, const std::string& message_) { | |
| context = context_; | |
| pcAddress = pcAddress_; | |
| reason = reason_; | |
| message = message_; | |
| } | |
| void EventClientNotifier::SendContextAdded(Context* context) { | |
| post_event(EventClientNotifier::SendContextAddedCallback, context); | |
| } | |
| void EventClientNotifier::SendContextAddedCallback(void* context) { | |
| TCFOutputStream out(&broadcastGroup->out); | |
| out.writeStringZ("E"); | |
| out.writeStringZ(RUN_CONTROL); | |
| out.writeStringZ("contextAdded"); | |
| // <array of context data> | |
| out.writeCharacter('['); | |
| WriteContext(*(Context*) context, out); | |
| out.writeCharacter(']'); | |
| out.writeZero(); | |
| out.writeComplete(); | |
| std::string contextID = ((Context*) context)->GetID(); | |
| LogTrace("EventClientNotifier::SendContextAdded ", "context id: %s", | |
| contextID.c_str()); | |
| } | |
| void EventClientNotifier::SendContextRemoved(Context* context, bool deleteContext) { | |
| SendRemovedEventParams* params = new SendRemovedEventParams(context, deleteContext); | |
| post_event(EventClientNotifier::SendContextRemovedCallback, params); | |
| } | |
| void EventClientNotifier::SendContextRemovedCallback(void* context) { | |
| SendRemovedEventParams* params = (SendRemovedEventParams*) context; | |
| TCFOutputStream out(&broadcastGroup->out); | |
| out.writeStringZ("E"); | |
| out.writeStringZ(RUN_CONTROL); | |
| out.writeStringZ("contextRemoved"); | |
| /* <array of context data> */ | |
| out.writeCharacter('['); | |
| out.writeString(params->context->GetID().c_str()); | |
| out.writeCharacter(']'); | |
| out.writeZero(); | |
| out.writeComplete(); | |
| LogTrace("EventClientNotifier::SendContextRemoved ", "context id: %d", | |
| params->context->GetID().c_str()); | |
| if (params->deleteContext) { | |
| ContextID id = params->context->GetID(); | |
| delete params->context; // this will delete the context and all its children | |
| int remained = ContextManager::getContexts().size(); | |
| trace(LOG_CONTEXT, "Context %s has died. \n\t\tNumber of contexts remained: %d\n", id.c_str(), remained); | |
| if (remained == 0) { | |
| debug_session_ends(); | |
| } | |
| } | |
| delete params; | |
| } | |
| void EventClientNotifier::SendExecutableEvent(Context* context, unsigned long pcAddress, const Properties& properties) { | |
| post_event(EventClientNotifier::SendExecutableEventCallback, | |
| new SendExeEventParams(context, pcAddress, properties)); | |
| } | |
| void EventClientNotifier::SendExecutableEventCallback(void* params) { | |
| SendExeEventParams* eventParams = (SendExeEventParams*) params; | |
| TCFOutputStream out(&broadcastGroup->out); | |
| out.writeStringZ("E"); | |
| out.writeStringZ(RUN_CONTROL); | |
| out.writeStringZ("contextSuspended"); | |
| out.writeString(eventParams->context->GetID()); | |
| out.writeZero(); | |
| out.writeLong(eventParams->pcAddress); | |
| out.writeZero(); | |
| out.writeString(REASON_SHAREDLIB); | |
| out.writeZero(); | |
| WriteProperties(eventParams->properties, out); | |
| out.writeZero(); | |
| out.writeComplete(); | |
| #if ENABLE_Trace | |
| PropertyValue exe; | |
| Properties::const_iterator iter = eventParams->properties.find(PROP_NAME); | |
| if (iter != eventParams->properties.end()) | |
| exe = iter->second; | |
| LogTrace("EventClientNotifier::SendExecutableEvent", | |
| "context id: %s executable: %s address: %X", | |
| eventParams->context->GetID().c_str(), | |
| exe.getType() == PVT_UNKNOWN ? exe.getStringValue().c_str() : "<none>", | |
| eventParams->pcAddress); | |
| #endif | |
| delete eventParams; | |
| } | |
| void EventClientNotifier::SendContextSuspended(Context* context, | |
| unsigned long pcAddress, const char* reason, const std::string& message) { | |
| post_event(EventClientNotifier::SendContextSuspendedCallback, | |
| new SendSuspendEventParams(context, pcAddress, reason, message)); | |
| } | |
| void EventClientNotifier::SendContextSuspendedCallback(void* params_) { | |
| SendSuspendEventParams* params = (SendSuspendEventParams*) params_; | |
| TCFOutputStream out(&broadcastGroup->out); | |
| out.writeStringZ("E"); | |
| out.writeStringZ(RUN_CONTROL); | |
| out.writeStringZ("contextSuspended"); | |
| out.writeString(params->context->GetID().c_str()); | |
| out.writeZero(); | |
| out.writeLong(params->pcAddress); | |
| out.writeZero(); | |
| out.writeString(params->reason); | |
| out.writeZero(); | |
| out.writeCharacter('{'); | |
| if (params->message.length() > 0) { | |
| out.writeString("message"); | |
| out.writeCharacter(':'); | |
| out.writeString(params->message.c_str()); | |
| } | |
| out.writeCharacter('}'); | |
| out.writeZero(); | |
| out.writeComplete(); | |
| LogTrace("EventClientNotifier::SendContextSuspended ", | |
| "context id: %s address: %X", params->context->GetID().c_str(), | |
| params->pcAddress); | |
| delete params; | |
| } | |
| void EventClientNotifier::SendContextException(Context* context, | |
| const std::string& description) { | |
| post_event(EventClientNotifier::SendContextExceptionCallback, | |
| new SendExceptionEventParams(context, description)); | |
| } | |
| void EventClientNotifier::SendContextExceptionCallback(void* params) { | |
| SendExceptionEventParams* eventParams = (SendExceptionEventParams*) params; | |
| TCFOutputStream out(&broadcastGroup->out); | |
| out.writeStringZ("E"); | |
| out.writeStringZ(RUN_CONTROL); | |
| out.writeStringZ("contextException"); | |
| out.writeString(eventParams->context->GetID()); | |
| out.writeZero(); | |
| out.writeCharacter('"'); | |
| out.writeString(eventParams->description.c_str()); | |
| out.writeCharacter('"'); | |
| out.writeZero(); | |
| out.writeComplete(); | |
| LogTrace("EventClientNotifier::SendContextException ", "context id: %s", | |
| eventParams->context->GetID().c_str()); | |
| delete eventParams; | |
| } | |
| void EventClientNotifier::WriteContext(Context& context, TCFOutputStream& out) { | |
| WriteProperties(context.GetProperties(), out); | |
| } | |
| void EventClientNotifier::WriteProperties(const Properties& properties, TCFOutputStream& out) { | |
| out.writeCharacter('{'); | |
| for (Properties::const_iterator iter = properties.begin(); | |
| iter != properties.end(); iter++) | |
| { | |
| if (iter != properties.begin()) | |
| out.writeCharacter(','); | |
| out.writeString(iter->first); | |
| out.writeCharacter(':'); | |
| iter->second.writeToTCFChannel(out); | |
| } | |
| out.writeCharacter('}'); | |
| } |