// -------------------------------------------------------------------------- // ReportStatus // /// Publish reported status to subscribers. /// /// @param status - string representation of the status to report. // -------------------------------------------------------------------------- void MessageManager::ReportStatus(std::string& status,uint8 severity) { // publish status NoticeRCP noticeRCP = THeapObject<StatusNotice>::Create(status, severity); NotifySubscribers(noticeRCP); }
bool ByteArray::Grow(uint32_t minimumCapacity) { if (minimumCapacity > m_capacity) { uint32_t newCapacity = m_capacity << 1; if (newCapacity < minimumCapacity) { newCapacity = minimumCapacity; } if (newCapacity < kGrowthIncr) { newCapacity = kGrowthIncr; } U8 *newArray = mmfx_new_array(uint8_t, newCapacity); if (!newArray) { return false; } if (m_array) { VMPI_memcpy(newArray, m_array, m_length); mmfx_delete_array(m_array); } VMPI_memset(newArray+m_length, 0, newCapacity-m_capacity); m_array = newArray; m_capacity = newCapacity; NotifySubscribers(); } return true; }
void ByteArray::Push(const U8 *data, uint32_t count) { Grow(m_length + count); VMPI_memcpy(m_array + m_length, data, count); m_length += count; NotifySubscribers(); }
void ByteArray::Push(U8 value) { if (m_length >= m_capacity) { Grow(m_length + 1); } m_array[m_length++] = value; NotifySubscribers(); }
U8& ByteArray::operator[] (uint32_t index) { if (m_length <= index) { Grow(index+1); m_length = index+1; NotifySubscribers(); } return m_array[index]; }
void ByteArray::SetLength(uint32_t newLength) { if(m_subscriberRoot && m_length < Domain::GLOBAL_MEMORY_MIN_SIZE) ThrowMemoryError(); if (newLength > m_capacity) { if (!Grow(newLength)) { ThrowMemoryError(); return; } } m_length = newLength; NotifySubscribers(); }
// -------------------------------------------------------------------------- // SendMessage // /// Send a message to the target. /// /// @param msgStr - string representation of the message to be sent. /// /// @returns bool - true if message sent successfully. // -------------------------------------------------------------------------- void MessageManager::SendMessage(std::string& msgStr) { // build a message reference counted pointer from the message string MessageRCP msgRCP = MessageFactory::GetInstance().CreateMessage(msgStr); // return if message is not created if (msgRCP.IsNull()) { return; } // get the message service type int svcType = msgRCP->GetSvcType(); // verify connection to a device has been established if (!DeviceMonitor::GetInstance().IsConnected()) { std::stringstream stream; stream << _T("Error: Unable to send message: ") << std::endl << _T("No device connection has been established.") << std::endl << std::endl; ReportStatus(stream.str(),ST_ERROR); return; } // open service if necessary ::EnterCriticalSection(&m_addServiceCS); if (!m_services[svcType]->IsOpen()) { if (!m_services[svcType]->OpenService(DeviceMonitor::GetInstance().GetDeviceName())) { // ??? TerminateDevice(); ::LeaveCriticalSection(&m_addServiceCS); return; } } ::LeaveCriticalSection(&m_addServiceCS); // send the message buffer if (m_services[svcType]->SendMsgBuf(msgRCP->GetMsgBuf())) { // notify subscribers message sent NoticeRCP noticeRCP = THeapObject<MsgNotice>::Create(msgRCP); NotifySubscribers(noticeRCP); return; } // close the service if send fails m_services[svcType]->CloseService(); }
// -------------------------------------------------------------------------- // ReportDevice // /// Respond to and publish reported device events /// /// @param reason - string description of the device event. /// /// @param type - uint8 type of device event. /// /// @param networkAdapters - vector of string representations of network /// adapters. // -------------------------------------------------------------------------- void MessageManager::ReportDevice ( std::string& reason, uint8 type, std::vector<std::string>& networkAdapters ) { // publish device notice NoticeRCP noticeRCP = THeapObject<DeviceNotice>::Create(reason,type,networkAdapters); NotifySubscribers(noticeRCP); // if the connection to a device is lost, close all open services if (type == DT_CONNECT_FAIL ||type == DT_DISCONNECT || type == DT_DETACH) { CloseServices(); } }
// -------------------------------------------------------------------------- // ProcessThread // /// The process thread repeatedly takes a buffer from the received queue, /// creates the appropriate Message and broadcasts the Message to all objects /// that have regestered to be notified. // -------------------------------------------------------------------------- void MessageManager::ProcessThread() { HANDLE waitHandles[2] = {m_hProcessExitEvent,m_hMsgEvent}; // process messages when available until exit is triggered while (::WaitForMultipleObjects(2,waitHandles,FALSE,INFINITE) != WAIT_OBJECT_0) { // get a message off the queue m_rspQueue.lock(); MsgBuf* pMsgBuf = m_rspQueue.front(); m_rspQueue.pop(); m_rspQueue.unlock(); // build a message reference counted pointer from the message buffer MessageRCP msgRCP = MessageFactory::GetInstance().CreateMessage(*pMsgBuf); if (!msgRCP.IsNull()) { // notify subscribers message received NoticeRCP noticeRCP = THeapObject<MsgNotice>::Create(msgRCP); NotifySubscribers(noticeRCP); } // delete the used message buffer delete pMsgBuf; // if no more messages to process, reset msg event TSQCriticalSection<MsgBuf*> localLock(m_rspQueue); if (m_rspQueue.empty()) { ::ResetEvent(m_hMsgEvent); } } }