//-------------------------------------------------------------------------------------------------- static le_result_t DcsNetSetDNS ( bool isIpv6, ///< [IN] it's of type IPv6 (true) or IPv4 (false) char *dns1Addr, ///< [IN] 1st DNS IP addr to be installed char *dns2Addr, ///< [IN] 2nd DNS IP addr to be installed int dnsAddrSize ///< [IN] array length of the DNS IP addresses to be installed ) { le_result_t ret = pa_dcs_SetDnsNameServers(dns1Addr, dns2Addr); if (ret != LE_OK) { LE_ERROR("Failed to set DNS addresses %s and %s", dns1Addr, dns2Addr); return ret; } if (isIpv6) { le_utf8_Copy(NetConfigBackup.newDnsIPv6[0], dns1Addr, dnsAddrSize, NULL); le_utf8_Copy(NetConfigBackup.newDnsIPv6[1], dns2Addr, dnsAddrSize, NULL); } else { le_utf8_Copy(NetConfigBackup.newDnsIPv4[0], dns1Addr, dnsAddrSize, NULL); le_utf8_Copy(NetConfigBackup.newDnsIPv4[1], dns2Addr, dnsAddrSize, NULL); } LE_INFO("Succeeded to set DNS addresses %s and %s", dns1Addr, dns2Addr); return ret; }
//-------------------------------------------------------------------------------------------------- static void StartMonitoringDirectorySocket ( Service_t* servicePtr ) //-------------------------------------------------------------------------------------------------- { le_event_FdHandlerRef_t handlerRef; char name[128]; size_t bytes; le_utf8_Copy(name, le_msg_GetProtocolIdStr(servicePtr->id.protocolRef), sizeof(name), &bytes); le_utf8_Copy(name + bytes, servicePtr->id.name, sizeof(name) - bytes, NULL); servicePtr->fdMonitorRef = le_event_CreateFdMonitor(name, servicePtr->directorySocketFd); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_READABLE, DirectorySocketReadable); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_READ_HANG_UP, DirectorySocketClosed); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_WRITE_HANG_UP, DirectorySocketClosed); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_ERROR, DirectorySocketError); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); }
void allParameters ( common_EnumExample_t a, uint32_t* bPtr, const uint32_t* dataPtr, size_t dataNumElements, uint32_t* outputPtr, size_t* outputNumElementsPtr, const char* label, char* response, size_t responseNumElements, char* more, size_t moreNumElements ) { int i; // Print out received values LE_PRINT_VALUE("%i", a); LE_PRINT_VALUE("%s", label); LE_PRINT_ARRAY("%i", dataNumElements, dataPtr); // Generate return values *bPtr = a; for (i=0; i<*outputNumElementsPtr; i++) { outputPtr[i] = i*a; } le_utf8_Copy(response, "response string", responseNumElements, NULL); le_utf8_Copy(more, "more info", moreNumElements, NULL); }
//-------------------------------------------------------------------------------------------------- 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. }
//-------------------------------------------------------------------------------------------------- le_result_t le_mrc_GetCellularNetworkMccMnc ( le_mrc_ScanInformation_Ref_t scanInformationRef, ///< [IN] Scan information reference char *mccPtr, ///< [OUT] Mobile Country Code size_t mccPtrSize, ///< [IN] mccPtr buffer size char *mncPtr, ///< [OUT] Mobile Network Code size_t mncPtrSize ///< [IN] mncPtr buffer size ) { pa_mrc_MobileCode_t mobileCode = { {0} }; pa_mrc_ScanInformation_t* scanInformationPtr = le_ref_Lookup(ScanInformationRefMap, scanInformationRef); if (scanInformationPtr == NULL) { LE_KILL_CLIENT("Invalid reference (%p) provided!", scanInformationRef); return LE_FAULT; } if (mccPtr == NULL) { LE_KILL_CLIENT("mccPtr is NULL"); return LE_FAULT; } if (mncPtr == NULL) { LE_KILL_CLIENT("mncPtr is NULL"); return LE_FAULT; } if ( pa_mrc_GetScanInformationCode(scanInformationPtr,&mobileCode) != LE_OK) { LE_WARN("Could not get scan information mobile code"); return LE_NOT_POSSIBLE; } if ( le_utf8_Copy(mccPtr,mobileCode.mcc,mccPtrSize,NULL) != LE_OK ) { LE_WARN("Could not copy all mcc"); return LE_OVERFLOW; } if ( le_utf8_Copy(mncPtr,mobileCode.mnc,mncPtrSize,NULL) != LE_OK ) { LE_WARN("Could not copy all mnc"); return LE_OVERFLOW; } return LE_OK; }
//-------------------------------------------------------------------------------------------------- properties_Iter_Ref_t properties_CreateIter ( const char* fileNamePtr ///< [IN] File name of the .properties file. ) { // Open the .properties file. FILE* filePtr; do { filePtr = fopen(fileNamePtr, "r"); } while ( (filePtr == NULL) && (errno == EINTR) ); if (filePtr == NULL) { LE_ERROR("File '%s' could not be opened. %m.", fileNamePtr); return NULL; } // Create the iterator. PropertiesIter_t* iterPtr = le_mem_ForceAlloc(PropertiesIterPool); iterPtr->streamPtr = filePtr; iterPtr->propertyBuf[0] = '\0'; iterPtr->keyPtr = NULL; iterPtr->valuePtr = NULL; // The stored file name is only used for debug log messages so it is fine if the file name gets // truncated. No need to check the return value. le_utf8_Copy(iterPtr->fileName, fileNamePtr, LIMIT_MAX_PATH_BYTES, NULL); return iterPtr; }
//-------------------------------------------------------------------------------------------------- proc_Ref_t proc_Create ( const char* cfgPathRootPtr, ///< [IN] The path in the config tree for this process. app_Ref_t appRef ///< [IN] Reference to the app that we are part of. ) { Process_t* procPtr = le_mem_ForceAlloc(ProcessPool); // Copy the config path. if (le_utf8_Copy(procPtr->cfgPathRoot, cfgPathRootPtr, sizeof(procPtr->cfgPathRoot), NULL) == LE_OVERFLOW) { LE_ERROR("Config path '%s' is too long.", cfgPathRootPtr); le_mem_Release(procPtr); return NULL; } procPtr->name = le_path_GetBasenamePtr(procPtr->cfgPathRoot, "/"); procPtr->appRef = appRef; procPtr->faultTime = 0; procPtr->paused = false; procPtr->pid = -1; // Processes that are not running are assigned -1 as its pid. procPtr->cmdKill = false; return procPtr; }
//-------------------------------------------------------------------------------------------------- static le_result_t ParseCommandLineArgs ( const int argc, const char* argv[] ) { le_result_t result = LE_OK; LE_INFO("Parsing Command Line Arguments"); if (argc != 2) { LE_INFO("Invalid Command Line Argument, argc = [%d]", argc); return LE_BAD_PARAMETER; } // Extract the Server's IP address le_utf8_Copy(NetworkSocketIpAddress, argv[0], sizeof(NetworkSocketIpAddress), NULL); LE_INFO("Setting Network Socket IP Address [%s]", NetworkSocketIpAddress); // Extract the Server's TCP Listening port int portNumber = atoi(argv[1]); // Verify the TCP Port range if (portNumber > 0xffff) { return LE_BAD_PARAMETER; } NetworkSocketTCPListeningPort = portNumber; LE_INFO("Setting Network Socket TCP Port [%" PRIu16 "]", NetworkSocketTCPListeningPort); return result; }
//-------------------------------------------------------------------------------------------------- le_result_t le_utf8_Append ( char* destStr, ///< [IN] The destination string. const char* srcStr, ///< [IN] The UTF-8 source string. const size_t destSize, ///< [IN] Size of the destination buffer in bytes. size_t* destStrLenPtr ///< [OUT] The number of bytes in the resultant destination string (not /// including the NULL-terminator). This parameter can be set to /// NULL if the destination string size is not needed. ) { // Check parameters. LE_ASSERT( (destStr != NULL) && (srcStr != NULL) && (destSize > 0) ); size_t destStrSize = strlen(destStr); le_result_t result = le_utf8_Copy(&(destStr[destStrSize]), srcStr, destSize - destStrSize, destStrLenPtr); if (destStrLenPtr) { *destStrLenPtr += destStrSize; } return result; }
//-------------------------------------------------------------------------------------------------- static le_result_t GetJsonStrField ( json_t *srcJsonPtr, ///<[IN] Json source object. const char *keyName, ///<[IN] Key in json object. char *const destStr, ///<[OUT] Destination where json value will be stored. size_t destLen ///<[IN] Max allowed length of destination string. ) { // Get key value. const char *srcJsonStr = json_string_value(json_object_get(srcJsonPtr, keyName)); if (srcJsonStr == NULL) { LE_WARN("Field: %s is missing in item", keyName); // No need to deallocate via le_mem_Release(), Delete method will take care of it. return LE_FAULT; } if (le_utf8_Copy(destStr, srcJsonStr, destLen, NULL) != LE_OK) { // sizeof(destStr)-1 because last one reserved for null char. LE_ERROR("Item field(%s:%s) too long, Allowed: %zd B", keyName, srcJsonStr, destLen - 1); return LE_FAULT; } return LE_OK; }
//-------------------------------------------------------------------------------------------------- le_result_t le_info_GetImei ( char* imeiPtr, ///< [OUT] The IMEI string. size_t len ///< [IN] The length of IMEI string. ) { pa_info_Imei_t imei; if (imeiPtr == NULL) { LE_KILL_CLIENT("imeiPtr is NULL !"); return LE_FAULT; } if(pa_info_GetIMEI(imei) != LE_OK) { LE_ERROR("Failed to get the IMEI"); imeiPtr[0] = '\0'; return LE_FAULT; } else { return (le_utf8_Copy(imeiPtr, imei, len, NULL)); } }
//-------------------------------------------------------------------------------------------------- le_result_t pa_mdc_GetInterfaceName ( uint32_t profileIndex, ///< [IN] The profile to use char* interfaceNameStr, ///< [OUT] The name of the network interface size_t interfaceNameStrSize ///< [IN] The size in bytes of the name buffer ) { // The interface name will always be of the form pppX, where X is an integer starting at zero. // Only one network interface is currently supported, thus X is 0, so hard-code the name. const char pppInterfaceNameStr[] = "ppp0"; le_mdc_ConState_t sessionState; le_result_t result; result = pa_mdc_GetSessionState(profileIndex, &sessionState); if ( (result != LE_OK) || (sessionState != LE_MDC_CONNECTED) ) { return LE_FAULT; } if (le_utf8_Copy(interfaceNameStr, pppInterfaceNameStr, interfaceNameStrSize, NULL) == LE_OVERFLOW ) { LE_ERROR("Interface name '%s' is too long", pppInterfaceNameStr); return LE_OVERFLOW; } return LE_OK; }
//-------------------------------------------------------------------------------------------------- void dstr_CopyFromCstr ( dstr_Ref_t destStrRef, ///< [OUT] The dynamic string to copy to. const char* sourceStrPtr ///< [IN] The C-style string to copy from. ) //-------------------------------------------------------------------------------------------------- { le_result_t result; dstr_Ref_t destSegmentRef = NewOrFirstSegmentRef(destStrRef); do { size_t bytesCopied = 0; result = le_utf8_Copy(destSegmentRef->body.value, sourceStrPtr, SEGMENT_SIZE, &bytesCopied); sourceStrPtr += bytesCopied; if (result == LE_OVERFLOW) { destSegmentRef = NewOrNextSegmentRef(destStrRef, destSegmentRef); } } while (result == LE_OVERFLOW); FreeAnyAfter(destStrRef, destSegmentRef); }
//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- static Service_t* GetService ( le_msg_ProtocolRef_t protocolRef, const char* serviceName ) //-------------------------------------------------------------------------------------------------- { ServiceId_t id; id.protocolRef = protocolRef; LE_FATAL_IF(le_utf8_Copy(id.name, serviceName, sizeof(id.name), NULL) == LE_OVERFLOW, "Service ID '%s' too long (should only be %zu bytes total).", serviceName, sizeof(id.name)); Service_t* servicePtr = le_hashmap_Get(ServiceMapRef, &id); if (servicePtr == NULL) { servicePtr = CreateService(protocolRef, serviceName); } else { le_mem_AddRef(servicePtr); } return servicePtr; }
//-------------------------------------------------------------------------------------------------- static void StartMonitoringDirectorySocket ( Service_t* servicePtr ) //-------------------------------------------------------------------------------------------------- { le_event_FdHandlerRef_t handlerRef; char name[LIMIT_MAX_MEM_POOL_NAME_BYTES]; char* destPtr = name; size_t spaceLeft = sizeof(name); size_t bytesCopied; le_utf8_Copy(destPtr, servicePtr->id.name, spaceLeft, &bytesCopied); destPtr += bytesCopied; spaceLeft -= bytesCopied; le_utf8_Copy(destPtr, ":", spaceLeft, &bytesCopied); destPtr += bytesCopied; spaceLeft -= bytesCopied; le_utf8_Copy(destPtr, le_msg_GetProtocolIdStr(servicePtr->id.protocolRef), spaceLeft, NULL); servicePtr->fdMonitorRef = le_event_CreateFdMonitor(name, servicePtr->directorySocketFd); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_WRITEABLE, DirectorySocketWriteable); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_READABLE, DirectorySocketReadable); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_READ_HANG_UP, DirectorySocketClosed); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_WRITE_HANG_UP, DirectorySocketClosed); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); handlerRef = le_event_SetFdHandler(servicePtr->fdMonitorRef, LE_EVENT_FD_ERROR, DirectorySocketError); le_event_SetFdHandlerContextPtr(handlerRef, servicePtr); }
//-------------------------------------------------------------------------------------------------- le_result_t pa_sim_GetSubscriberPhoneNumber ( char *phoneNumberStr, ///< [OUT] The phone Number size_t phoneNumberStrSize ///< [IN] Size of phoneNumberStr ) { return le_utf8_Copy(phoneNumberStr,"",phoneNumberStrSize, NULL); }
// todo: This function may eventually replace all usage of UnpackString() above. // Maybe there should also be a PackDataString() function as well? // Unused attribute is needed because this function may not always get used __attribute__((unused)) static void* UnpackDataString(void* msgBufPtr, void* dataPtr, size_t dataSize) { // Number of bytes copied from msg buffer, not including null terminator size_t numBytes; // todo: For now, assume the string will always fit in the buffer. This may not always be true. le_utf8_Copy( dataPtr, msgBufPtr, dataSize, &numBytes ); return ( msgBufPtr + (numBytes + 1) ); }
//-------------------------------------------------------------------------------------------------- le_event_FdMonitorRef_t le_event_CreateFdMonitor ( const char* name, ///< [in] Name of the object (for diagnostics). int fd ///< [in] File descriptor to be monitored for events. ) //-------------------------------------------------------------------------------------------------- { // Get a pointer to the thread-specific event loop data record. event_PerThreadRec_t* perThreadRecPtr = thread_GetEventRecPtr(); // Allocate the object. FdMonitor_t* fdMonitorPtr = le_mem_ForceAlloc(FdMonitorPool); // Initialize the object. fdMonitorPtr->link = LE_DLS_LINK_INIT; fdMonitorPtr->fd = fd; fdMonitorPtr->threadRecPtr = perThreadRecPtr; memset(fdMonitorPtr->handlerArray, 0, sizeof(fdMonitorPtr->handlerArray)); // To start with, no events are in the set to be monitored. They will be added as handlers // are registered for them. (Although, EPOLLHUP and EPOLLERR will always be monitored // regardless of what flags we specify). We use epoll in "level-triggered mode". fdMonitorPtr->epollEvents = 0; // Assume that the event should wake up the system; can be changed later. fdMonitorPtr->wakeUp = true; // Copy the name into it. if (le_utf8_Copy(fdMonitorPtr->name, name, sizeof(fdMonitorPtr->name), NULL) == LE_OVERFLOW) { LE_WARN("FD Monitor object name '%s' truncated to '%s'.", name, fdMonitorPtr->name); } LOCK // Create a safe reference for the object. fdMonitorPtr->safeRef = le_ref_CreateRef(FdMonitorRefMap, fdMonitorPtr); // Add it to the thread's FD Monitor list. le_dls_Queue(&perThreadRecPtr->fdMonitorList, &fdMonitorPtr->link); // Tell epoll(7) to start monitoring this fd. struct epoll_event ev; ev.events = fdMonitorPtr->epollEvents; ev.data.ptr = fdMonitorPtr->safeRef; if (epoll_ctl(perThreadRecPtr->epollFd, EPOLL_CTL_ADD, fd, &ev) == -1) { LE_FATAL("epoll_ctl(ADD) failed for fd %d. errno = %d (%m)", fd, errno); } UNLOCK return fdMonitorPtr->safeRef; }
//-------------------------------------------------------------------------------------------------- static ThreadObj_t* CreateThread ( const char* name, ///< [in] Name of the thread. le_thread_MainFunc_t mainFunc, ///< [in] The thread's main function. void* context ///< [in] Value to pass to mainFunc when it is called. ) { // Create a new thread object. ThreadObj_t* threadPtr = le_mem_ForceAlloc(ThreadPool); // Copy the name. We will make the names unique by adding the thread ID later so we allow any // string as the name. LE_WARN_IF(le_utf8_Copy(threadPtr->name, name, sizeof(threadPtr->name), NULL) == LE_OVERFLOW, "Thread name '%s' has been truncated to '%s'.", name, threadPtr->name); // Initialize the pthreads attribute structure. LE_ASSERT(pthread_attr_init(&(threadPtr->attr)) == 0); // Make sure when we create the thread it takes it attributes from the attribute object, // as opposed to inheriting them from its parent thread. if (pthread_attr_setinheritsched(&(threadPtr->attr), PTHREAD_EXPLICIT_SCHED) != 0) { LE_CRIT("Could not set scheduling policy inheritance for thread '%s'.", name); } // By default, Legato threads are not joinable (they are detached). if (pthread_attr_setdetachstate(&(threadPtr->attr), PTHREAD_CREATE_DETACHED) != 0) { LE_CRIT("Could not set the detached state for thread '%s'.", name); } threadPtr->isJoinable = false; threadPtr->isStarted = false; threadPtr->mainFunc = mainFunc; threadPtr->context = context; threadPtr->destructorList = LE_SLS_LIST_INIT; threadPtr->threadHandle = 0; memset(&threadPtr->mutexRec, 0, sizeof(threadPtr->mutexRec)); memset(&threadPtr->semaphoreRec, 0, sizeof(threadPtr->semaphoreRec)); memset(&threadPtr->eventRec, 0, sizeof(threadPtr->eventRec)); memset(&threadPtr->timerRec, 0, sizeof(threadPtr->timerRec)); // Create a safe reference for this object. Lock(); threadPtr->safeRef = le_ref_CreateRef(ThreadRefMap, threadPtr); Unlock(); return threadPtr; }
//-------------------------------------------------------------------------------------------------- le_result_t pa_mrc_GetCurrentNetwork ( char *nameStr, ///< [OUT] the home network Name size_t nameStrSize, ///< [IN] the nameStr size char *mccStr, ///< [OUT] the mobile country code size_t mccStrNumElements, ///< [IN] the mccStr size char *mncStr, ///< [OUT] the mobile network code size_t mncStrNumElements ///< [IN] the mncStr size ) { le_result_t res = LE_OK; if (RadioPower != LE_ON) { *nameStr = '\0'; return LE_NOT_POSSIBLE; } if (nameStr != NULL) { res = le_utf8_Copy(nameStr, PA_SIMU_MRC_DEFAULT_NAME, nameStrSize, NULL); if (res != LE_OK) return res; } if (mccStr != NULL) { res = le_utf8_Copy(mccStr, PA_SIMU_MRC_DEFAULT_MCC, mccStrNumElements, NULL); if (res != LE_OK) return res; } if (mncStr != NULL) { res = le_utf8_Copy(mncStr, PA_SIMU_MRC_DEFAULT_MNC, mncStrNumElements, NULL); } return res; }
// ------------------------------------------------------------------------------------------------- static tu_UserRef_t CreateUserInfo ( uid_t userId, ///< [IN] The linux Id of the user in question. const char* userName, ///< [IN] The name of the user. const char* treeName ///< [IN] The name of the default tree for this user. ) // ------------------------------------------------------------------------------------------------- { tu_UserRef_t userRef = le_mem_ForceAlloc(UserPoolRef); userRef->userId = userId; LE_ASSERT(le_utf8_Copy(userRef->userName, userName, sizeof(userRef->userName), NULL) == LE_OK); LE_ASSERT(le_utf8_Copy(userRef->treeName, treeName, sizeof(userRef->treeName), NULL) == LE_OK); LE_ASSERT(le_hashmap_Put(UserCollectionRef, &userRef->userId, userRef) == NULL); LE_DEBUG("** Allocated new user object <%p>: '%s', %u with default tree, '%s'.", userRef, userRef->userName, userRef->userId, userRef->treeName); return userRef; }
//-------------------------------------------------------------------------------------------------- le_result_t le_mem_GetName ( le_mem_PoolRef_t pool, ///< [IN] The memory pool. char* namePtr, ///< [OUT] Buffer to store the name of memory pool. size_t bufSize ///< [IN] Size of the buffer namePtr points to. ) { LE_ASSERT(pool != NULL); Lock(); le_result_t result = le_utf8_Copy(namePtr, pool->name, bufSize, NULL); Unlock(); return result; }
//-------------------------------------------------------------------------------------------------- static le_result_t GetProcessNameFromPid ( pid_t pId, ///< [IN] The pid of the process whose name to find char* name, ///< [OUT] A buffer to receive the name of the app size_t length ///< [IN] The size of the buffer that receives the name ) { char pathStr[LIMIT_MAX_PATH_BYTES] = ""; char procPathStr[LIMIT_MAX_PATH_BYTES] = ""; if (name != NULL) { // on linux, /proc/[pid]/cmdline contains the command and arguments separated by '\0's int result = snprintf(pathStr, sizeof(pathStr), "/proc/%d/cmdline", pId); if (result < 0 || result >= LIMIT_MAX_PATH_BYTES) { return LE_NOT_FOUND; } int fd = open(pathStr, O_RDONLY); if (fd) { result = read (fd, procPathStr, LIMIT_MAX_PATH_BYTES); fd_Close(fd); if (result == 0) { return LE_FAULT; } else if (strnlen(procPathStr, LIMIT_MAX_PATH_BYTES) == LIMIT_MAX_PATH_BYTES) { // We need the first parameter of the command line, which is path to a process. // This shouldn't be longer than LIMIT_MAX_PATH_BYTES. return LE_OVERFLOW; } // strip the path char* procNamePtr = le_path_GetBasenamePtr(procPathStr, "/"); return le_utf8_Copy(name, procNamePtr, length, NULL); } } else { return LE_FAULT; } return LE_OK; }
//-------------------------------------------------------------------------------------------------- void StartClient ( const char* serviceInstanceName ///< [IN] ) { // The instance name must not be an empty string if ( serviceInstanceName[0] == '\0' ) { LE_FATAL("Service instance name is empty"); } // If this is not the first time this function is called, compare against stored instance name. if ( GlobalServiceInstanceName[0] != '\0' ) { if ( strcmp(GlobalServiceInstanceName, serviceInstanceName) == 0 ) { LE_DEBUG("Called with duplicate name"); } else { // This is an error because the user application is likely not connecting to the // service that they expect. LE_ERROR("Service instance name cannot be changed from '%s' to '%s'", GlobalServiceInstanceName, serviceInstanceName); } // Since the function was called before, there is nothing further to do. return; } // This is the first time the function is called. Store the instance name and init the client. LE_FATAL_IF(le_utf8_Copy(GlobalServiceInstanceName, serviceInstanceName, sizeof(GlobalServiceInstanceName), NULL) == LE_OVERFLOW, "Service ID '%s' too long (should only be %zu bytes total).", serviceInstanceName, sizeof(GlobalServiceInstanceName)); LE_DEBUG("======= Starting Client %s ========", serviceInstanceName); InitClient(); // Although InitClientThreadData() returns a value, it is not needed here. InitClientThreadData(serviceInstanceName); }
//-------------------------------------------------------------------------------------------------- le_result_t dstr_CopyToCstr ( char* destStrPtr, ///< [OUT] The destiniation string buffer. size_t destStrMax, ///< [IN] The maximum string the buffer can handle. const dstr_Ref_t sourceStrRef, ///< [IN] The dynamic string to copy to said buffer. size_t* totalCopied ///< [IN] If supplied, this is the total number of bytes copied ///< to the target string buffer. ) //-------------------------------------------------------------------------------------------------- { dstr_Ref_t segmentRef = NULL; if (totalCopied) { *totalCopied = 0; } for (segmentRef = FirstSegmentRef(sourceStrRef); segmentRef != NULL; segmentRef = NextSegmentRef(sourceStrRef, segmentRef)) { size_t bytesCopied = 0; le_result_t result = le_utf8_Copy(destStrPtr, segmentRef->body.value, destStrMax, &bytesCopied); if (totalCopied) { *totalCopied += bytesCopied; } if (result == LE_OVERFLOW) { return LE_OVERFLOW; } LE_FATAL_IF(result != LE_OK, "Unexpected result code returned, %s.", LE_RESULT_TXT(result)); destStrMax -= bytesCopied; destStrPtr += bytesCopied; } return LE_OK; }
//-------------------------------------------------------------------------------------------------- le_result_t ni_GetNodeValueString ( ni_IteratorRef_t iteratorRef, ///< The iterator object to access. const char* pathPtr, ///< Optional path to another node in the tree. char* destBufferPtr, ///< The buffer to copy string data into. size_t bufferMax, ///< The maximum size of the string buffer. const char* defaultPtr ///< If the value can not be found, use this one instead. ) //-------------------------------------------------------------------------------------------------- { tdb_NodeRef_t nodeRef = ni_GetNode(iteratorRef, pathPtr); if (nodeRef == NULL) { return le_utf8_Copy(destBufferPtr, defaultPtr, bufferMax, NULL); } return tdb_GetValueAsString(nodeRef, destBufferPtr, bufferMax, defaultPtr); }
//-------------------------------------------------------------------------------------------------- le_result_t pa_mrc_GetScanInformationName ( pa_mrc_ScanInformation_t *scanInformationPtr, ///< [IN] The scan information char *namePtr, ///< [OUT] Name of operator size_t nameSize ///< [IN] The size in bytes of the namePtr buffer ) { if ((!scanInformationPtr) || (!namePtr)) { return LE_NOT_POSSIBLE; } // @TODO Handle other names than default SIM MCC/MNC if ( (0 == strcmp(scanInformationPtr->mobileCode.mcc, PA_SIMU_SIM_DEFAULT_MCC)) && (0 == strcmp(scanInformationPtr->mobileCode.mnc, PA_SIMU_SIM_DEFAULT_MNC)) ) { return le_utf8_Copy(namePtr, PA_SIMU_MRC_DEFAULT_NAME, nameSize, NULL); } return LE_NOT_POSSIBLE; }
//-------------------------------------------------------------------------------------------------- le_result_t properties_GetValueForKey ( const char* fileNamePtr, ///< [IN] File name of the .properties file. const char* keyPtr, ///< [IN] Key to get the value for. char* bufPtr, ///< [OUT] Buffer to hold the value string. size_t bufSize ///< [IN] Size of the buffer. ) { // Get an iterator to the app's info.properties file. properties_Iter_Ref_t iter = properties_CreateIter(fileNamePtr); if (iter == NULL) { return LE_FAULT; } // Look through the name value pairs to find the key. while (1) { le_result_t result = properties_NextNode(iter); if (result == LE_OK) { // Get the key. if (strcmp(properties_GetKey(iter), keyPtr) == 0) { // Get and return the value. le_result_t r = le_utf8_Copy(bufPtr, properties_GetValue(iter), bufSize, NULL); properties_DeleteIter(iter); return r; } } else { properties_DeleteIter(iter); return result; } } }
//-------------------------------------------------------------------------------------------------- static Service_t* CreateService ( le_msg_ProtocolRef_t protocolRef, const char* serviceName ) //-------------------------------------------------------------------------------------------------- { Service_t* servicePtr = le_mem_ForceAlloc(ServicePoolRef); servicePtr->id.protocolRef = protocolRef; le_result_t result = le_utf8_Copy(servicePtr->id.name, serviceName, sizeof(servicePtr->id.name), NULL); LE_FATAL_IF(result != LE_OK, "Service ID '%s' too long (should only be %zu bytes total).", serviceName, sizeof(servicePtr->id.name)); servicePtr->state = LE_MSG_SERVICE_HIDDEN; servicePtr->directorySocketFd = -1; servicePtr->fdMonitorRef = NULL; servicePtr->serverThread = NULL; // NULL indicates no server in this process. servicePtr->sessionList = LE_DLS_LIST_INIT; servicePtr->recvHandler = NULL; servicePtr->recvContextPtr = NULL; // Initialize the close handlers dls servicePtr->closeListPtr = LE_DLS_LIST_INIT; // Initialize the open handlers dls servicePtr->openListPtr = LE_DLS_LIST_INIT; le_hashmap_Put(ServiceMapRef, &servicePtr->id, servicePtr); return servicePtr; }