error_t socketInit(void) { uint_t i; uint_t j; //Create a mutex to prevent simultaneous access to sockets if(!osCreateMutex(&socketMutex)) { //Failed to create mutex return ERROR_OUT_OF_RESOURCES; } //Initialize socket related data memset(socketTable, 0, sizeof(socketTable)); //Loop through socket descriptors for(i = 0; i < SOCKET_MAX_COUNT; i++) { //Set socket identifier socketTable[i].descriptor = i; //Create an event object to track socket events if(!osCreateEvent(&socketTable[i].event)) { //Clean up side effects for(j = 0; j < i; j++) osDeleteEvent(&socketTable[j].event); //Delete mutex osDeleteMutex(&socketMutex); //Report an error return ERROR_OUT_OF_RESOURCES; } } //Successful initialization return NO_ERROR; }
error_t socketPoll(SocketEventDesc *eventDesc, uint_t size, OsEvent *extEvent, systime_t timeout) { uint_t i; bool_t status; OsEvent *event; OsEvent eventObject; //Check parameters if(!eventDesc || !size) return ERROR_INVALID_PARAMETER; //Try to use the supplied event object to receive notifications if(!extEvent) { //Create an event object only if necessary if(!osCreateEvent(&eventObject)) { //Report an error return ERROR_OUT_OF_RESOURCES; } //Reference to the newly created event event = &eventObject; } else { //Reference to the external event event = extEvent; } //Loop through descriptors for(i = 0; i < size; i++) { //Clear event flags eventDesc[i].eventFlags = 0; //Subscribe to the requested events socketRegisterEvents(eventDesc[i].socket, event, eventDesc[i].eventMask); } //Block the current task until an event occurs status = osWaitForEvent(event, timeout); //Any socket event is in the signaled state? if(status) { //Loop through descriptors for(i = 0; i < size; i++) { //Retrieve event flags for the current socket socketGetEvents(eventDesc[i].socket, &eventDesc[i].eventFlags); //Clear unnecessary flags eventDesc[i].eventFlags &= eventDesc[i].eventMask; } } //Unsubscribe previously registered events for(i = 0; i < size; i++) socketUnregisterEvents(eventDesc[i].socket); //Reset event object before exiting... osResetEvent(event); //Release previously allocated resources if(!extEvent) osDeleteEvent(&eventObject); //Return status code return status ? NO_ERROR : ERROR_TIMEOUT; }
error_t httpServerInit(HttpServerContext *context, const HttpServerSettings *settings) { error_t error; uint_t i; //Debug message TRACE_INFO("Initializing HTTP server...\r\n"); //Ensure the parameters are valid if(context == NULL || settings == NULL) return ERROR_INVALID_PARAMETER; //Check user settings if(settings->maxConnections == 0 || settings->connections == NULL) return ERROR_INVALID_PARAMETER; //Clear the HTTP server context memset(context, 0, sizeof(HttpServerContext)); //Save user settings context->settings = *settings; //Client connections context->connections = settings->connections; //Create a semaphore to limit the number of simultaneous connections if(!osCreateSemaphore(&context->semaphore, context->settings.maxConnections)) return ERROR_OUT_OF_RESOURCES; //Loop through client connections for(i = 0; i < context->settings.maxConnections; i++) { //Create an event object to manage connection lifetime if(!osCreateEvent(&context->connections[i].startEvent)) return ERROR_OUT_OF_RESOURCES; } #if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED) //Create a mutex to prevent simultaneous access to the nonce cache if(!osCreateMutex(&context->nonceCacheMutex)) return ERROR_OUT_OF_RESOURCES; #endif //Open a TCP socket context->socket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP); //Failed to open socket? if(!context->socket) return ERROR_OPEN_FAILED; //Set timeout for blocking functions error = socketSetTimeout(context->socket, INFINITE_DELAY); //Any error to report? if(error) return error; //Associate the socket with the relevant interface error = socketBindToInterface(context->socket, settings->interface); //Unable to bind the socket to the desired interface? if(error) return error; //Bind newly created socket to port 80 error = socketBind(context->socket, &IP_ADDR_ANY, settings->port); //Failed to bind socket to port 80? if(error) return error; //Place socket in listening state error = socketListen(context->socket, settings->backlog); //Any failure to report? if(error) return error; //Successful initialization return NO_ERROR; }