//-------------------------------------------------------------------------------------------------- static void LoadIpcBindingConfig ( void ) { int result = system("sdir load"); if (result == -1) { LE_FATAL("Failed to fork child process. (%m)"); } else if (WIFEXITED(result)) { int exitCode = WEXITSTATUS(result); if (exitCode != 0) { LE_FATAL("Couldn't load IPC binding config. `sdir load` exit code: %d.", exitCode); } } else if (WIFSIGNALED(result)) { int sigNum = WTERMSIG(result); LE_FATAL("Couldn't load IPC binding config. `sdir load` received signal: %d.", sigNum); } }
// ------------------------------------------------------------------------------------------------- static void* ThreadMainFunction ( void* expectedPolicy ///< The expected Linux scheduling policy (SCHED_IDLE or SCHED_OTHER). ) // ------------------------------------------------------------------------------------------------- { LE_INFO("Checking scheduling policy..."); int schedPolicy = sched_getscheduler(0); if (schedPolicy == -1) { LE_FATAL("Failed to fetch scheduling policy (error %d).", errno); } if (expectedPolicy != (void*)(size_t)schedPolicy) { LE_FATAL("Expected policy %p. Got %p.", expectedPolicy, (void*)(size_t)schedPolicy); } else { LE_INFO("Policy correct."); } return NULL; }
//-------------------------------------------------------------------------------------------------- void fa_event_TriggerEvent_NoLock ( event_PerThreadRec_t* portablePerThreadRecPtr ) { static const uint64_t writeBuff = 1; // Write the value 1 to increment the eventfd by 1. event_LinuxPerThreadRec_t* perThreadRecPtr = CONTAINER_OF(portablePerThreadRecPtr, event_LinuxPerThreadRec_t, portablePerThreadRec); ssize_t writeSize; for (;;) { writeSize = write(perThreadRecPtr->eventQueueFd, &writeBuff, sizeof(writeBuff)); if (writeSize == sizeof(writeBuff)) { return; } else { if ((writeSize == -1) && (errno != EINTR)) { LE_FATAL("write() failed with errno %d.", errno); } else { LE_FATAL("write() returned %zd! (expected %zd)", writeSize, sizeof(writeBuff)); } } } }
//-------------------------------------------------------------------------------------------------- uint64_t fa_event_WaitForEvent ( event_PerThreadRec_t* portablePerThreadRecPtr ) { uint64_t readBuff; ssize_t readSize; event_LinuxPerThreadRec_t* perThreadRecPtr = CONTAINER_OF(portablePerThreadRecPtr, event_LinuxPerThreadRec_t, portablePerThreadRec); for (;;) { readSize = read(perThreadRecPtr->eventQueueFd, &readBuff, sizeof(readBuff)); if (readSize == sizeof(readBuff)) { return readBuff; } else { if ((readSize == -1) && (errno != EINTR)) { LE_FATAL("read() failed with errno %d.", errno); } else { LE_FATAL("read() returned %zd! (expected %zd)", readSize, sizeof(readBuff)); } } } }
//-------------------------------------------------------------------------------------------------- void le_pm_Relax(le_pm_WakeupSourceRef_t w) { WakeupSource_t *ws, *entry; // Validate the reference, check if it exists ws = ToWakeupSource(w); // If the wakeup source is NULL then the client will have // been killed and we can just return if (NULL == ws) return; entry = (WakeupSource_t*)le_hashmap_Get(PowerManager.locks, ws->name); if (!entry) LE_FATAL("Wakeup source '%s' not created.\n", ws->name); if (!entry->taken) { LE_ERROR("Wakeup source '%s' already released.", entry->name); return; } // write to /sys/power/wake_unlock if (0 > write(PowerManager.wu, entry->name, strlen(entry->name))) LE_FATAL("Error releasing wakeup soruce '%s', errno = %d.", entry->name, errno); entry->taken = LE_OFF; return; }
//-------------------------------------------------------------------------------------------------- static _ClientThreadData_t* InitClientThreadData ( const char* serviceInstanceName ) { // Open a session. le_msg_ProtocolRef_t protocolRef; le_msg_SessionRef_t sessionRef; // The instance name must not be an empty string if ( serviceInstanceName[0] == '\0' ) { LE_FATAL("Undefined client service instance name (Was StartClient() called?)"); } protocolRef = le_msg_GetProtocolRef(PROTOCOL_ID_STR, sizeof(_Message_t)); sessionRef = le_msg_CreateSession(protocolRef, serviceInstanceName); le_msg_SetSessionRecvHandler(sessionRef, ClientIndicationRecvHandler, NULL); le_msg_OpenSessionSync(sessionRef); // Store the client sessionRef in thread-local storage, since each thread requires // its own sessionRef. _ClientThreadData_t* clientThreadPtr = le_mem_ForceAlloc(_ClientThreadDataPool); clientThreadPtr->sessionRef = sessionRef; if (pthread_setspecific(_ThreadDataKey, clientThreadPtr) != 0) { LE_FATAL("pthread_setspecific() failed!"); } return clientThreadPtr; }
//-------------------------------------------------------------------------------------------------- static void LoadECallSettings ( int32_t* hMinAccuracyPtr, int32_t* dirMinAccuracyPtr ) { char psapStr[LE_MDMDEFS_PHONE_NUM_MAX_BYTES] = {0}; LE_DEBUG("Start reading eCall app settings in Configuration Tree"); le_cfg_IteratorRef_t eCallCfgRef = le_cfg_CreateReadTxn(CFG_ECALL_APP_PATH); // Get PSAP if (le_cfg_NodeExists(eCallCfgRef, CFG_NODE_PSAP)) { if ( le_cfg_GetString(eCallCfgRef, CFG_NODE_PSAP, psapStr, sizeof(psapStr), "") != LE_OK ) { LE_FATAL("No node value set for '%s', exit the app!", CFG_NODE_PSAP); } LE_DEBUG("eCall settings, PSAP number is %s", psapStr); if (le_ecall_SetPsapNumber(psapStr) != LE_OK) { LE_FATAL("Cannot set PSAP number, exit the app!"); } } else { LE_FATAL("No value set for '%s', restart the app!", CFG_NODE_PSAP); } // Get minimum horizontal accuracy if (le_cfg_NodeExists(eCallCfgRef, CFG_NODE_H_MIN_ACCURACY)) { *hMinAccuracyPtr = le_cfg_GetInt(eCallCfgRef, CFG_NODE_H_MIN_ACCURACY, DEFAULT_H_ACCURACY); LE_DEBUG("eCall app settings, horizontal accuracy is %d meter(s)", *hMinAccuracyPtr); } else { *hMinAccuracyPtr = DEFAULT_H_ACCURACY; } // Get minimum direction accuracy if (le_cfg_NodeExists(eCallCfgRef, CFG_NODE_DIR_MIN_ACCURACY)) { *dirMinAccuracyPtr = le_cfg_GetInt(eCallCfgRef, CFG_NODE_DIR_MIN_ACCURACY, DEFAULT_DIR_ACCURACY); LE_DEBUG("eCall app settings, direction accuracy is %d degree(s)", *dirMinAccuracyPtr); } else { *dirMinAccuracyPtr = DEFAULT_DIR_ACCURACY; } le_cfg_CancelTxn(eCallCfgRef); }
//-------------------------------------------------------------------------------------------------- le_result_t pa_audioSimu_CheckAudioPathSet ( void ) { le_audio_If_t inItf; le_audio_If_t outItf; for (inItf = 0; inItf < LE_AUDIO_NUM_INTERFACES; inItf++) { for (outItf = 0; outItf < LE_AUDIO_NUM_INTERFACES; outItf++) { if ( inItf == outItf ) { // audio path can't be built between a stream and the same stream LE_ASSERT( BuildAudioPath[inItf][outItf] == 0 ); } else if ( IS_OUTPUT_STREAM(inItf) ) { // if the input stream is an output, it is not a valuable path LE_ASSERT( BuildAudioPath[inItf][outItf] == 0 ); } else if ( IS_INPUT_STREAM(inItf) ) { if ( IS_OUTPUT_STREAM(outItf) ) { // this is an expected audio path. It should be set only once LE_ASSERT( BuildAudioPath[inItf][outItf] == 1 ); } else if (IS_INPUT_STREAM(outItf)) { // if the output stream is an input, it is not a valuable path LE_ASSERT( BuildAudioPath[inItf][outItf] == 0 ); } else { LE_FATAL("Unknown audio path"); } } else { LE_FATAL("Unknown audio path"); } } } return LE_OK; }
//-------------------------------------------------------------------------------------------------- le_sem_Ref_t CreateSemaphore ( const char* nameStr, int initialCount, bool isTraceable ) //-------------------------------------------------------------------------------------------------- { // Allocate a semaphore object and initialize it. Semaphore_t* semaphorePtr = le_mem_ForceAlloc(SemaphorePoolRef); semaphorePtr->semaphoreListLink = LE_DLS_LINK_INIT; semaphorePtr->waitingList = LE_DLS_LIST_INIT; pthread_mutex_init(&semaphorePtr->waitingListMutex, NULL); // Default attributes = Fast mutex. semaphorePtr->isTraceable = isTraceable; if (le_utf8_Copy(semaphorePtr->nameStr, nameStr, sizeof(semaphorePtr->nameStr), NULL) == LE_OVERFLOW) { LE_WARN("Semaphore name '%s' truncated to '%s'.", nameStr, semaphorePtr->nameStr); } // Initialize the underlying POSIX semaphore shared between thread. int result = sem_init(&semaphorePtr->semaphore,0, initialCount); if (result != 0) { LE_FATAL("Failed to set the semaphore . errno = %d (%m).", errno); } // Add the semaphore to the process's Semaphore List. LOCK_SEMAPHORE_LIST(); le_dls_Queue(&SemaphoreList, &semaphorePtr->semaphoreListLink); UNLOCK_SEMAPHORE_LIST(); return semaphorePtr; }
//-------------------------------------------------------------------------------------------------- le_result_t le_sem_TryWait ( le_sem_Ref_t semaphorePtr ///< [IN] Pointer to the semaphore ) { // TODO: Implement this. // if (semaphorePtr->isTraceable) // { // } // else { int result; result = sem_trywait(&semaphorePtr->semaphore); if (result != 0) { if ( errno == EAGAIN ) { return LE_WOULD_BLOCK; } else { LE_FATAL("Thread '%s' failed to trywait on semaphore '%s'. Error code %d (%m).", le_thread_GetMyName(), semaphorePtr->nameStr, result); } } } return LE_OK; }
static void SigUser2Handler(int sigNum) { LE_INFO("%s received through fd handler.", strsignal(sigNum)); switch (checkCount) { case 2: { // Send to the other thread. But the other thread should not get it. checkCount++; LE_ASSERT(kill(getpid(), SIGUSR1) == 0); // Make sure that the signal to thread 1 is sent first. sleep(1); // Send to ourself and we should get it checkCount++; LE_ASSERT(kill(getpid(), SIGUSR2) == 0); break; } case 4: { LE_INFO("======== Signal Events Test Completed (PASSED) ========"); exit(EXIT_SUCCESS); } default: LE_FATAL("Should not be here."); } }
int main(int argc, char* argv[]) { arg_SetArgs((size_t)argc, (char**)argv); LE_DEBUG("== Starting Executable '%s' ==", STRINGIZE(LE_EXECUTABLE_NAME)); LE_LOG_SESSION = log_RegComponent( STRINGIZE(LE_COMPONENT_NAME), &LE_LOG_LEVEL_FILTER_PTR); // Connect to the Log Control Daemon. // The sooner we can connect to the Log Control Daemon, the better, because that is when // we obtain any non-default log settings that have been set using the interactive log // control tool. However, we can't do that until we have a working IPC messaging system. // However, the Log Control Daemon shouldn't try to connect to itself. // Also, the Service Directory shouldn't try to use the messaging system, so it can't // connect to the Log Control Daemon either. Besides, the Service Directory starts before // the Log Control Daemon starts. #ifndef NO_LOG_CONTROL log_ConnectToControlDaemon(); #endif //@todo: Block all signals that the user intends to handle with signal events. // Queue up all the component initialization functions to be called by the Event Loop after // it processes any messages that were received from the Log Control Daemon. event_QueueComponentInit(_le_event_InitializeComponent); LE_DEBUG("== Starting Event Processing Loop =="); le_event_RunLoop(); LE_FATAL("SHOULDN'T GET HERE!"); }
//-------------------------------------------------------------------------------------------------- void msgService_SendServiceId ( le_msg_ServiceRef_t serviceRef, ///< [in] Pointer to the service whose ID is to be sent. int socketFd ///< [in] File descriptor of the connected socket to send on. ) //-------------------------------------------------------------------------------------------------- { svcdir_ServiceId_t serviceId; memset(&serviceId, 0, sizeof(serviceId)); serviceId.maxProtocolMsgSize = le_msg_GetProtocolMaxMsgSize(serviceRef->id.protocolRef); le_utf8_Copy(serviceId.protocolId, le_msg_GetProtocolIdStr(serviceRef->id.protocolRef), sizeof(serviceId.protocolId), NULL); le_utf8_Copy(serviceId.serviceName, serviceRef->id.name, sizeof(serviceId.serviceName), NULL); le_result_t result = unixSocket_SendDataMsg(socketFd, &serviceId, sizeof(serviceId)); if (result != LE_OK) { LE_FATAL("Failed to send. Result = %d (%s)", result, LE_RESULT_TXT(result)); } // NOTE: This is only done when the socket is newly opened, so this shouldn't ever // return LE_NO_MEMORY to indicate send buffers being full. }
int main(int argc, char** argv) { struct pollfd pollControl; le_sms_ConnectService(); // Register a callback function to be called when an SMS arrives. (void)le_sms_AddRxMessageHandler(SmsRxHandler, NULL); printf("Waiting for SMS messages to arrive...\n"); // Get the Legato event loop "readyness" file descriptor and put it in a pollfd struct // configured to detect "ready to read". pollControl.fd = le_event_GetFd(); pollControl.events = POLLIN; while (true) { // Block until the file descriptor is "ready to read". int result = poll(&pollControl, 1, -1); if (result > 0) { // The Legato event loop needs servicing. Keep servicing it until there's nothing left. while (le_event_ServiceLoop() == LE_OK) { /* le_event_ServiceLoop() has more to do. Need to call it again. */ } } else { LE_FATAL("poll() failed with errno %m."); } } }
//-------------------------------------------------------------------------------------------------- void StopClient ( void ) { _ClientThreadData_t* clientThreadPtr = pthread_getspecific(_ThreadDataKey); // If the thread specific data is NULL, then there is no current client session. if (clientThreadPtr == NULL) { LE_ERROR("Trying to stop non-existent client session for '%s' service", GlobalServiceInstanceName); } else { le_msg_CloseSession( clientThreadPtr->sessionRef ); // Need to delete the thread specific data, since it is no longer valid. If a new // client session is started, new thread specific data will be allocated. le_mem_Release(clientThreadPtr); if (pthread_setspecific(_ThreadDataKey, NULL) != 0) { LE_FATAL("pthread_setspecific() failed!"); } LE_DEBUG("======= Stopping Client %s ========", GlobalServiceInstanceName); } }
//-------------------------------------------------------------------------------------------------- le_result_t le_clk_ConvertToUTCString ( le_clk_Time_t time, ///< [IN] date/time to convert const char* formatSpecStrPtr, ///< [IN] Format specifier string, using conversion /// specifiers defined for strftime(). char* destStrPtr, ///< [OUT] Destination for the formatted date/time string size_t destSize, ///< [IN] Size of the destination buffer in bytes. size_t* numBytesPtr ///< [OUT] Number of bytes copied, not including NULL-terminator. /// Parameter can be set to NULL if the number of /// bytes copied is not needed. ) { struct tm brokenTime; le_result_t result; if (gmtime_r(&time.sec, &brokenTime) == NULL) { LE_FATAL("Cannot convert time into UTC broken down time."); } result = FormatBrokenTime(time, brokenTime, formatSpecStrPtr, destStrPtr, destSize, numBytesPtr); return result; }
//-------------------------------------------------------------------------------------------------- static void StopMonitoringFd ( FdMonitor_t* fdMonitorPtr ) //-------------------------------------------------------------------------------------------------- { TRACE("Deleting fd %d (%s) from thread's epoll set.", fdMonitorPtr->fd, fdMonitorPtr->name); if (epoll_ctl(fdMonitorPtr->threadRecPtr->epollFd, EPOLL_CTL_DEL, fdMonitorPtr->fd, NULL) == -1) { if (errno == EBADF) { TRACE("epoll_ctl(DEL) for fd %d resulted in EBADF. Probably because connection" " closed before deleting FD Monitor %s.", fdMonitorPtr->fd, fdMonitorPtr->name); } else if (errno == ENOENT) { TRACE("epoll_ctl(DEL) for fd %d resulted in ENOENT. Probably because we stopped" " monitoring before deleting the FD Monitor %s.", fdMonitorPtr->fd, fdMonitorPtr->name); } else { LE_FATAL("epoll_ctl(DEL) failed for fd %d. errno = %d (%m)", fdMonitorPtr->fd, errno); } } }
//-------------------------------------------------------------------------------------------------- static void UpdateEpollFd ( FdMonitor_t* monitorPtr ) //-------------------------------------------------------------------------------------------------- { struct epoll_event ev; ev.events = monitorPtr->epollEvents; ev.data.ptr = monitorPtr->safeRef; int epollFd = monitorPtr->threadRecPtr->epollFd; if (epoll_ctl(epollFd, EPOLL_CTL_MOD, monitorPtr->fd, &ev) == -1) { if (errno == EBADF) { TRACE("epoll_ctl(MOD) for fd %d resulted in EBADF. Probably because connection" " closed before deleting FD Monitor %s.", monitorPtr->fd, monitorPtr->name); } else { LE_FATAL("epoll_ctl(MOD) failed for fd %d and events %x on monitor '%s'. Errno %d (%m)", monitorPtr->fd, monitorPtr->epollEvents, monitorPtr->name, errno); } } }
//-------------------------------------------------------------------------------------------------- const char* GetFdEventTypeName ( le_event_FdEventType_t eventType ) //-------------------------------------------------------------------------------------------------- { switch (eventType) { case LE_EVENT_FD_READABLE: return "readable"; case LE_EVENT_FD_READABLE_URGENT: return "readable-urgent"; case LE_EVENT_FD_WRITEABLE: return "writeable"; case LE_EVENT_FD_WRITE_HANG_UP: return "write-hangup"; case LE_EVENT_FD_READ_HANG_UP: return "read-hangup"; case LE_EVENT_FD_ERROR: return "error"; } LE_FATAL("Unknown event type %d.", eventType); }
//-------------------------------------------------------------------------------------------------- static void* PThreadStartRoutine ( void* threadObjPtr ) { void* returnValue; ThreadObj_t* threadPtr = threadObjPtr; // WARNING: This code must be very carefully crafted to avoid the possibility of hitting // a cancellation point before pthread_cleanup_push() is called. Otherwise, it's // possible that any destructor function set before the thread was started will // not get executed, which could create intermittent resource leaks. // Store the Thread Object pointer in thread-local storage so GetCurrentThreadPtr() can // find it later. // NOTE: pthread_setspecific() is not a cancellation point. if (pthread_setspecific(ThreadLocalDataKey, threadPtr) != 0) { LE_FATAL("pthread_setspecific() failed!"); } // Push the default destructor onto the thread's cleanup stack. pthread_cleanup_push(CleanupThread, threadPtr); // Perform thread specific init thread_InitThread(); // Call the user's main function. returnValue = threadPtr->mainFunc(threadPtr->context); // Pop the default destructor and call it. pthread_cleanup_pop(1); return returnValue; }
//-------------------------------------------------------------------------------------------------- static void CaptureDebugData ( proc_Ref_t procRef, ///< [IN] The process reference. bool isRebooting ///< [IN] Is the supervisor going to reboot the system? ) { char command[LIMIT_MAX_PATH_BYTES]; int s = snprintf(command, sizeof(command), "saveLogs %s %s %s %s", app_GetIsSandboxed(procRef->appRef) ? "SANDBOXED" : "NOTSANDBOXED", app_GetName(procRef->appRef), procRef->name, isRebooting ? "REBOOT" : ""); if (s >= sizeof(command)) { LE_FATAL("Could not create command, buffer is too small. " "Buffer is %zd bytes but needs to be %d bytes.", sizeof(command), s); } int r = system(command); if (!WIFEXITED(r)) { LE_ERROR("Could not backup core files."); } }
//-------------------------------------------------------------------------------------------------- event_PerThreadRec_t* fa_event_CreatePerThreadInfo ( void ) { event_LinuxPerThreadRec_t* recPtr = le_mem_ForceAlloc(PerThreadPool); // Create the epoll file descriptor for this thread. This will be used to monitor for // events on various file descriptors. recPtr->epollFd = epoll_create1(0); LE_FATAL_IF(recPtr->epollFd < 0, "epoll_create1(0) failed with errno %d.", errno); // Open an eventfd for this thread. This will be uses to signal to the epoll fd that there // are Event Reports on the Event Queue. recPtr->eventQueueFd = eventfd(0, 0); LE_FATAL_IF(recPtr->eventQueueFd < 0, "eventfd() failed with errno %d.", errno); // Add the eventfd to the list of file descriptors to wait for using epoll_wait(). struct epoll_event ev; memset(&ev, 0, sizeof(ev)); ev.events = EPOLLIN | EPOLLWAKEUP; ev.data.ptr = NULL; // This being set to NULL is what tells the main event loop that this // is the Event Queue FD, rather than another FD that is being // monitored. if (epoll_ctl(recPtr->epollFd, EPOLL_CTL_ADD, recPtr->eventQueueFd, &ev) == -1) { LE_FATAL( "epoll_ctl(ADD) failed for fd %d. errno = %d", recPtr->eventQueueFd, errno); } return &recPtr->portablePerThreadRec; }
//-------------------------------------------------------------------------------------------------- void msgService_Init ( void ) //-------------------------------------------------------------------------------------------------- { // Create and initialize the pool of Service objects. ServicePoolRef = le_mem_CreatePool("MessagingServices", sizeof(Service_t)); le_mem_ExpandPool(ServicePoolRef, MAX_EXPECTED_SERVICES); le_mem_SetDestructor(ServicePoolRef, ServiceDestructor); // Create and initialize the pool of event handlers objects. HandlerEventPoolRef = le_mem_CreatePool("HandlerEventPool", sizeof(SessionEventHandler_t)); le_mem_ExpandPool(HandlerEventPoolRef, MAX_EXPECTED_SERVICES*6); // Create safe reference map for add references. HandlersRefMap = le_ref_CreateMap("HandlersRef", MAX_EXPECTED_SERVICES*6); // Create the Service Map. ServiceMapRef = le_hashmap_Create("MessagingServices", MAX_EXPECTED_SERVICES, ComputeServiceIdHash, AreServiceIdsTheSame); // Create the key to be used to identify thread-local data records containing the Message // Reference when running a Service's message receive handler. int result = pthread_key_create(&ThreadLocalRxMsgKey, NULL); if (result != 0) { LE_FATAL("Failed to create thread local key: result = %d (%s).", result, strerror(result)); } }
//-------------------------------------------------------------------------------------------------- le_result_t le_clk_ConvertToLocalTimeString ( le_clk_Time_t time, ///< [IN] date/time to convert const char* formatSpecStrPtr, ///< [IN] Format specifier string, using conversion /// specifiers defined for strftime(). char* destStrPtr, ///< [OUT] Destination for the formatted date/time string size_t destSize, ///< [IN] Size of the destination buffer in bytes. size_t* numBytesPtr ///< [OUT] Number of bytes copied, not including NULL-terminator. /// Parameter can be set to NULL if the number of /// bytes copied is not needed. ) { struct tm brokenTime; le_result_t result; // According to the documentation for localtime_r(), for portable code, tzset() should be // called before localtime_r(). tzset(); if (localtime_r(&time.sec, &brokenTime) == NULL) { LE_FATAL("Cannot convert Absolute time into local broken down time."); } result = FormatBrokenTime(time, brokenTime, formatSpecStrPtr, destStrPtr, destSize, numBytesPtr); return result; }
//-------------------------------------------------------------------------------------------------- le_result_t pa_mrc_GetRadioAccessTechInUse ( le_mrc_Rat_t* ratPtr ///< [OUT] The Radio Access Technology. ) { le_result_t res; char ratStr[513]; res = le_cfg_QuickGetString(PA_SIMU_CFG_MODEM_ROOT "/radio/rat", ratStr, sizeof(ratStr), PA_SIMU_MRC_DEFAULT_RAT); if (res != LE_OK) { LE_FATAL("Unable to get SIM state"); } LE_DEBUG("Current RAT: %s", ratStr); *ratPtr = ConvertStringToRat(ratStr); if (ratPtr == LE_MRC_RAT_UNKNOWN) { return LE_FAULT; } return LE_OK; }
std::string DataValue::encodeAsJSON(void) const { std::string json; switch (this->type) { case DATAROUTER_BOOLEAN: json = (this->value.b) ? "true" : "false"; break; case DATAROUTER_INTEGER: json = std::to_string(this->value.i); break; case DATAROUTER_FLOAT: json = std::to_string(this->value.f); break; case DATAROUTER_STRING: json = escapeStringForJSON(this->value.s); break; default: LE_FATAL("Value has unknown type"); break; } return json; }
//-------------------------------------------------------------------------------------------------- static void Reboot ( void ) { LE_FATAL("Supervisor going down to trigger reboot."); }
//-------------------------------------------------------------------------------------------------- static void CheckLabel ( const char* labelPtr ///< [IN] Label to check. ) { // Check lengths. size_t labelSize = strlen(labelPtr); LE_FATAL_IF(labelSize == 0, "SMACK label cannot be empty."); LE_FATAL_IF(labelSize > LIMIT_MAX_SMACK_LABEL_LEN, "SMACK label length, %zd chars, is too long. Labels must be less than %d chars", labelSize, LIMIT_MAX_SMACK_LABEL_LEN); // Check for invalid characters. LE_FATAL_IF(labelPtr[0] == '-', "SMACK label '%s' is invalid because it begins with '-'.", labelPtr); int i; for (i = 0; i < labelSize; i++) { char c = labelPtr[i]; if ( !isprint(c) || !isascii(c) || (c == '/') || (c == '\\') || (c == '\'') || (c == '"') ) { LE_FATAL("SMACK label '%s' contain invalid character(s).", labelPtr); } } }
//-------------------------------------------------------------------------------------------------- static void PopContext ( Parser_t* parserPtr ) //-------------------------------------------------------------------------------------------------- { // Don't do anything if a client handler has already stopped parsing. if (NotStopped(parserPtr)) { // Pop the top one and release it. le_sls_Link_t* linkPtr = le_sls_Pop(&parserPtr->contextStack); le_mem_Release(CONTAINER_OF(linkPtr, Context_t, link)); // Check the new context le_json_ContextType_t context = GetContext(parserPtr)->type; switch (context) { case LE_JSON_CONTEXT_DOC: // We've finished parsing the whole document. // Automatically stop parsing and report the document end to the client. StopParsing(parserPtr); Report(parserPtr, LE_JSON_DOC_END); break; case LE_JSON_CONTEXT_OBJECT: // We've finished parsing an object member. // Expect a comma separator or the end of the object next. parserPtr->next = EXPECT_COMMA_OR_OBJECT_END; break; case LE_JSON_CONTEXT_MEMBER: // We've finished parsing the value of an object member. // This is also the end of the member, so pop that context too. PopContext(parserPtr); break; case LE_JSON_CONTEXT_ARRAY: // We've finished parsing an array element value. // Expect a comma separator or the end of the array next. parserPtr->next = EXPECT_COMMA_OR_ARRAY_END; break; // These are all leaf contexts. That is, we should never find one of these // contexts after popping another one off the stack. case LE_JSON_CONTEXT_STRING: case LE_JSON_CONTEXT_NUMBER: case LE_JSON_CONTEXT_TRUE: case LE_JSON_CONTEXT_FALSE: case LE_JSON_CONTEXT_NULL: LE_FATAL("Unexpected context after pop: %s", le_json_GetContextName(context)); } } }
static inline Client_t *to_Client_t(void *c) { Client_t *cl = (Client_t *)c; if (!cl || PM_CLIENT_COOKIE != cl->cookie) LE_FATAL("Error: bad client %p.", c); return cl; }