//-------------------------------------------------------------------------------------------------- void AtClientServer ( SharedData_t* sharedDataPtr ) { struct sockaddr_un addr; int epollFd; struct epoll_event event; char monitorName[MAX_LEN_MONITOR_NAME]; le_fdMonitor_Ref_t fdMonitorRef; LE_INFO("AtClientServer Started !!!"); ClientData.socketFd = socket(AF_UNIX, SOCK_STREAM, 0); LE_ASSERT(ClientData.socketFd != -1); epollFd = epoll_create1(0); LE_ASSERT(epollFd != -1); event.events = EPOLLIN | EPOLLRDHUP; event.data.fd = ClientData.socketFd; LE_ASSERT(epoll_ctl(epollFd, EPOLL_CTL_ADD, ClientData.socketFd, &event) == 0); memset(&addr, 0, sizeof(addr)); addr.sun_family= AF_UNIX; strncpy(addr.sun_path, sharedDataPtr->devPathPtr, sizeof(addr.sun_path)-1); LE_ASSERT(bind(ClientData.socketFd, (struct sockaddr*) &addr, sizeof(addr)) != -1); LE_ASSERT(listen(ClientData.socketFd, 1) != -1); le_sem_Post(sharedDataPtr->semRef); ClientData.connFd = accept(ClientData.socketFd, NULL, NULL); LE_ASSERT(ClientData.connFd != -1); le_sem_Post(sharedDataPtr->semRef); snprintf(monitorName, sizeof(monitorName), "Monitor-%d", ClientData.connFd); fdMonitorRef = le_fdMonitor_Create(monitorName, dup(ClientData.connFd), RxNewData, POLLIN | POLLPRI | POLLRDHUP); le_fdMonitor_SetContextPtr(fdMonitorRef, sharedDataPtr); }
//-------------------------------------------------------------------------------------------------- le_json_ParsingSessionRef_t le_json_Parse ( int fd, ///< File descriptor to read the JSON document from. le_json_EventHandler_t eventHandler, ///< Function to call when normal parsing events happen. le_json_ErrorHandler_t errorHandler, ///< Function to call when errors happen. void* opaquePtr ///< Opaque pointer to be fetched by handlers using le_json_GetOpaquePtr(). ) //-------------------------------------------------------------------------------------------------- { // Create a Parser. Parser_t* parserPtr = NewParser(eventHandler, errorHandler, opaquePtr); parserPtr->fd = fd; parserPtr->fdMonitor = le_fdMonitor_Create("le_json", fd, FdEventHandler, POLLIN); le_fdMonitor_SetContextPtr(parserPtr->fdMonitor, parserPtr); // Create the top-level context and push it onto the context stack. PushContext(parserPtr, LE_JSON_CONTEXT_DOC, eventHandler); return parserPtr; }
//-------------------------------------------------------------------------------------------------- LE_SHARED le_result_t le_comm_RegisterHandleMonitor (void* handle, le_comm_CallbackHandlerFunc_t handlerFunc, short events) { char socketName[80]; HandleRecord_t* connectionRecordPtr = (HandleRecord_t*) handle; // Store the Asynchronous Receive callback function AsyncReceiveHandlerFuncPtr = handlerFunc; #ifdef SOCKET_SERVER if (connectionRecordPtr->isListeningFd) { // // Listening Socket Fd // // Store the Asynchronous Connection callback function AsyncConnectionHandlerFuncPtr = handlerFunc; // No need to proceed further - return return LE_OK; } #endif LE_INFO("Registering handle_monitor callback"); snprintf(socketName, sizeof(socketName) - 1, "inetSocket-%d", connectionRecordPtr->fd); // Set the Polling Events PollingEvents = events; // Create thread to monitor FD handle for activity, as defined by the events FdMonitorRef = le_fdMonitor_Create(socketName, connectionRecordPtr->fd, (le_fdMonitor_HandlerFunc_t) AsyncRecvHandler, PollingEvents); LE_INFO("Successfully registered handle_monitor callback, events [0x%x]", events); return LE_OK; }
//-------------------------------------------------------------------------------------------------- void le_sig_SetEventHandler ( int sigNum, ///< The signal to set the event handler for. See /// parameter documentation in comments above. le_sig_EventHandlerFunc_t sigEventHandler ///< The event handler to call when a signal is /// received. ) { // Check parameters. if ( (sigNum == SIGKILL) || (sigNum == SIGSTOP) || (sigNum == SIGFPE) || (sigNum == SIGILL) || (sigNum == SIGSEGV) || (sigNum == SIGBUS) || (sigNum == SIGABRT) || (sigNum == SIGIOT) || (sigNum == SIGTRAP) || (sigNum == SIGSYS) ) { LE_FATAL("Signal event handler for %s is not allowed.", strsignal(sigNum)); } // Get the monitor object for this thread. MonitorObj_t* monitorObjPtr = pthread_getspecific(SigMonKey); if (monitorObjPtr == NULL) { if (sigEventHandler == NULL) { // Event handler already does not exist so we don't need to do anything, just return. return; } else { // Create the monitor object monitorObjPtr = le_mem_ForceAlloc(MonitorObjPool); monitorObjPtr->handlerObjList = LE_DLS_LIST_INIT; monitorObjPtr->fd = -1; monitorObjPtr->monitorRef = NULL; // Add it to the thread's local data. LE_ASSERT(pthread_setspecific(SigMonKey, monitorObjPtr) == 0); } } // See if a handler for this signal already exists. HandlerObj_t* handlerObjPtr = FindHandlerObj(sigNum, &(monitorObjPtr->handlerObjList)); if (handlerObjPtr == NULL) { if (sigEventHandler == NULL) { // Event handler already does not exist so we don't need to do anything, just return. return; } else { // Create the handler object. handlerObjPtr = le_mem_ForceAlloc(HandlerObjPool); // Set the handler. handlerObjPtr->link = LE_DLS_LINK_INIT; handlerObjPtr->handler = sigEventHandler; handlerObjPtr->sigNum = sigNum; // Add the handler object to the list. le_dls_Queue(&(monitorObjPtr->handlerObjList), &(handlerObjPtr->link)); } } else { if (sigEventHandler == NULL) { // Remove the handler object from the list. le_dls_Remove(&(monitorObjPtr->handlerObjList), &(handlerObjPtr->link)); } else { // Just update the handler. handlerObjPtr->handler = sigEventHandler; } } // Recreate the signal mask. sigset_t sigSet; LE_ASSERT(sigemptyset(&sigSet) == 0); le_dls_Link_t* handlerLinkPtr = le_dls_Peek(&(monitorObjPtr->handlerObjList)); while (handlerLinkPtr != NULL) { HandlerObj_t* handlerObjPtr = CONTAINER_OF(handlerLinkPtr, HandlerObj_t, link); LE_ASSERT(sigaddset(&sigSet, handlerObjPtr->sigNum) == 0); handlerLinkPtr = le_dls_PeekNext(&(monitorObjPtr->handlerObjList), handlerLinkPtr); } // Update or create the signal fd. monitorObjPtr->fd = signalfd(monitorObjPtr->fd, &sigSet, SFD_NONBLOCK); if (monitorObjPtr->fd == -1) { LE_FATAL("Could not set signal event handler: %m"); } // Create a monitor fd if it doesn't already exist. if (monitorObjPtr->monitorRef == NULL) { // Create the monitor name using SIG_STR + thread name. char monitorName[LIMIT_MAX_THREAD_NAME_BYTES + sizeof(SIG_STR)] = SIG_STR; LE_ASSERT(le_utf8_Copy(monitorName + sizeof(SIG_STR), le_thread_GetMyName(), LIMIT_MAX_THREAD_NAME_BYTES + sizeof(SIG_STR), NULL) == LE_OK); // Create the monitor. monitorObjPtr->monitorRef = le_fdMonitor_Create(monitorName, monitorObjPtr->fd, OurSigHandler, POLLIN); } }
//-------------------------------------------------------------------------------------------------- LE_SHARED void* le_comm_Create ( const int argc, ///< [IN] Number of strings pointed to by argv. const char *argv[], ///< [IN] Pointer to an array of character strings. le_result_t* resultPtr ///< [OUT] Return Code ) { // // Create Connection Socket // // Verify result pointer is valid if (resultPtr == NULL) { LE_ERROR("resultPtr is NULL"); return NULL; } if (!le_hashmap_isEmpty(HandleRecordByFileDescriptor)) { LE_ERROR("Sanity Check Failure: Hashmap is not empty"); *resultPtr = LE_FAULT; return NULL; } // Parse the Command Line arguments to extract the IP Address and TCP Port number *resultPtr = ParseCommandLineArgs(argc, argv); if (*resultPtr != LE_OK) { return NULL; } HandleRecord_t* connectionRecordPtr = le_mem_AssertAlloc(HandleRecordPoolRef); // Initialize the connection record connectionRecordPtr->fd = -1; connectionRecordPtr->isListeningFd = false; connectionRecordPtr->parentRecordPtr = NULL; // Create the socket connectionRecordPtr->fd = socket(AF_INET, SOCK_STREAM, 0); if (connectionRecordPtr->fd < 0) { LE_WARN("Failed to create AF_INET socket. Errno = %d", errno); // Set the result pointer with a fault code *resultPtr = LE_FAULT; connectionRecordPtr->fd = -1; return (connectionRecordPtr); } #ifdef SOCKET_SERVER struct sockaddr_in sockAddr; // Prepare the sockaddr_in structure sockAddr.sin_family = AF_INET; sockAddr.sin_addr.s_addr = INADDR_ANY; sockAddr.sin_port = htons(NetworkSocketTCPListeningPort); // Bind if (bind(connectionRecordPtr->fd, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) < 0) { LE_WARN("Failed to bind socket, fd %d, result = %d", connectionRecordPtr->fd, errno); // Close the Socket handle close(connectionRecordPtr->fd); connectionRecordPtr->fd = -1; // Set the result pointer with a fault code *resultPtr = LE_FAULT; return (connectionRecordPtr); } // Listen if (listen(connectionRecordPtr->fd, NETWORK_SOCKET_MAX_CONNECT_REQUEST_BACKLOG) != 0) { LE_WARN("Server socket listen() call failed with errno %d", errno); } LE_INFO("Registering handle_monitor callback"); char socketName[80]; snprintf(socketName, sizeof(socketName) - 1, "inetSocket-%d", connectionRecordPtr->fd); // Create thread to monitor FD handle for activity, as defined by the events ListeningFdMonitorRef = le_fdMonitor_Create(socketName, connectionRecordPtr->fd, (le_fdMonitor_HandlerFunc_t) &ListeningRecvHandler, POLLIN); // Flag as a listening socket connectionRecordPtr->isListeningFd = true; LE_INFO("Successfully registered listening callback function, events [0x%x]", POLLIN); #endif LE_INFO("Created AF_INET Socket, fd %d", connectionRecordPtr->fd); // Set the return code to reflect if client can proceed with connect call, or whether it needs to // wait for asynchronous connection #ifdef SOCKET_SERVER *resultPtr = LE_IN_PROGRESS; #else *resultPtr = LE_OK; #endif // Store the Handle record le_hashmap_Put(HandleRecordByFileDescriptor, (void*)(intptr_t) connectionRecordPtr->fd, connectionRecordPtr); return (connectionRecordPtr); }
static int mqttClient_connect(mqttClient_t* clientData) { struct sockaddr_in address; struct addrinfo *result = NULL; struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL}; int rc = LE_OK; LE_ASSERT(clientData); if (clientData->session.sock != MQTT_CLIENT_INVALID_SOCKET) { LE_WARN("socket already connected"); goto cleanup; } rc = getaddrinfo(clientData->session.config.brokerUrl, NULL, &hints, &result); if (rc) { LE_ERROR("getaddrinfo() failed(%d)", rc); goto cleanup; } struct addrinfo* res = result; while (res) { if (res->ai_family == AF_INET) { result = res; break; } res = res->ai_next; } if (result->ai_family == AF_INET) { address.sin_port = htons(clientData->session.config.portNumber); address.sin_family = AF_INET; address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr; } else { LE_ERROR("find IP('%s') failed", clientData->session.config.brokerUrl); rc = LE_FAULT; goto cleanup; } clientData->session.sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); if (clientData->session.sock == -1) { LE_ERROR("socket() failed(%d)", errno); rc = clientData->session.sock; goto cleanup; } clientData->session.sockFdMonitor = le_fdMonitor_Create(MQTT_CLIENT_SOCKET_MONITOR_NAME, clientData->session.sock, mqttClient_socketFdEventHandler, POLLIN | POLLOUT); if (!clientData->session.sockFdMonitor) { LE_ERROR("le_fdMonitor_Create() failed"); rc = LE_FAULT; goto cleanup; } le_fdMonitor_SetContextPtr(clientData->session.sockFdMonitor, clientData); clientData->session.tx.ptr = clientData->session.tx.buf; clientData->session.rx.ptr = clientData->session.rx.buf; rc = connect(clientData->session.sock, (struct sockaddr*)&address, sizeof(address)); if (rc == -1) { rc = le_timer_Start(clientData->session.connTimer); if (rc) { LE_ERROR("le_timer_Start() failed(%d)", rc); goto cleanup; } if (errno != EINPROGRESS) { LE_ERROR("connect() failed(%d)", errno); rc = LE_FAULT; goto cleanup; } LE_DEBUG("connecting('%s')", clientData->session.config.brokerUrl); rc = LE_OK; goto cleanup; } LE_DEBUG("connected('%s')", clientData->session.config.brokerUrl); cleanup: freeaddrinfo(result); if (rc && (clientData->session.sock != MQTT_CLIENT_INVALID_SOCKET)) { int err = mqttClient_close(clientData); if (err) { LE_ERROR("mqttClient_close() failed(%d)", err); goto cleanup; } } return rc; }