/*---------------------------------------------------------------------------*/ void _rtp_timer_process_expired_jobs (RTPTimerJob* timerList) { RTPTimerJob *job = timerList->next; long timeDifferenceMsec; unsigned long currentMsec = rtp_get_system_msec(); void (*timerFunction) (int,void*); void* timerData; while (job != timerList) { rtpTimerNextToProcess = job->next; timeDifferenceMsec = (long) (currentMsec - job->scheduledTimeMsec); if (timeDifferenceMsec > 0) { DLLIST_REMOVE(job); if (job->repeat == RTP_TIMER_REPEAT_INFINITE) { DLLIST_INSERT_BEFORE(&rtpTimerNewList, job); job->listId = RTP_TIMER_LIST_NEW; } else { if (job->repeat > 0) { /* if this timer has more repeats left, add it to the new list */ job->repeat--; DLLIST_INSERT_BEFORE(&rtpTimerNewList, job); job->listId = RTP_TIMER_LIST_NEW; } else { DLLIST_INIT(job); job->listId = RTP_TIMER_LIST_NONE; } } if (job->timerFunction) { timerFunction = job->timerFunction; timerData = job->timerData; rtp_sig_mutex_release(rtpTimerLock); timerFunction(0, timerData); rtp_sig_mutex_claim(rtpTimerLock); } } else { break; } job = rtpTimerNextToProcess; } rtpTimerNextToProcess = 0; }
/*---------------------------------------------------------------------------*/ int rtp_timer_init (void) { if (rtpTimerInitialized == 0) { if (rtp_sig_mutex_alloc(&rtpTimerLock, 0) >= 0) { if (rtp_sig_semaphore_alloc(&rtpTimerSignal, 0) >= 0) { RTP_THREAD newThread; DLLIST_INIT(&rtpTimerNewList); DLLIST_INIT(&rtpTimerActiveList); rtpTimerNextToProcess = 0; if (rtp_thread_spawn (&newThread, _rtp_timer_thread, 0, 0, 2, 0) >= 0) { rtpTimerInitialized = 1; return (0); } rtp_sig_semaphore_free(rtpTimerSignal); } else { rtp_printf("rtp_timer_init - rtp_sig_semaphore_alloc failed!\n"); } rtp_sig_mutex_free(rtpTimerLock); } else { rtp_printf("rtp_timer_init - rtp_sig_mutex_alloc failed!"); } return (-1); } rtpTimerInitialized++; return (0); }
/*---------------------------------------------------------------------------*/ HTTPAuthenticationHost * _HTTP_NewHost ( const HTTP_CHAR* hostName, HTTP_UINT16 port ) { HTTPAuthenticationHost * host = (HTTPAuthenticationHost *) rtp_malloc(sizeof(HTTPAuthenticationHost)); if (host) { tc_memset(host, 0, sizeof(HTTPAuthenticationHost)); tc_strncpy(host->hostName, hostName, HTTP_CFG_MAX_HOSTNAME_LEN-1); host->hostName[HTTP_CFG_MAX_HOSTNAME_LEN-1] = 0; host->port = port; DLLIST_INIT(&host->realmList); } return (host); }
/*---------------------------------------------------------------------------*/ int HTTP_ServerAddAuthRealm (HTTPServerContext *server, const HTTP_CHAR *realmName, HTTPAuthRealmPath *pathList, HTTP_INT16 numPaths, HTTPAuthRealmUser *userList, HTTP_INT16 numUsers, HTTPAuthScheme scheme) { HTTPServerAuthRealm *realm; /* first try to find an existing realm with the same name */ realm = (HTTPServerAuthRealm *) server->realmList.next; while (realm != (HTTPServerAuthRealm *) &server->realmList) { if (!rtp_strcmp(realmName, realm->realmName)) { /* already exists; first need to remove it */ return (-1); } realm = (HTTPServerAuthRealm *) realm->node.next; } realm = _HTTP_AllocServerAuthRealm(); if (realm) { DLLIST_INSERT_BEFORE(&server->realmList, &realm->node); DLLIST_INIT(&realm->activeNonceList); realm->pathList = pathList; realm->userList = userList; realm->scheme = scheme; realm->numPaths = numPaths; realm->numUsers = numUsers; rtp_strncpy(realm->realmName, realmName, HTTP_SERVER_NAME_LEN-1); return (0); } return (-1); }
/*---------------------------------------------------------------------------*/ int rtp_timer_stop (RTP_TIMER* timer) { int result = -1; rtp_sig_mutex_claim(rtpTimerLock); switch (timer->listId) { case RTP_TIMER_LIST_NONE: break; case RTP_TIMER_LIST_ACTIVE: if (rtpTimerNextToProcess == timer) { rtpTimerNextToProcess = timer->next; } /* intentional fall-through */ case RTP_TIMER_LIST_NEW: DLLIST_REMOVE(timer); DLLIST_INIT(timer); timer->listId = RTP_TIMER_LIST_NONE; result = 0; if (!rtpTimerThreadAwake) { rtpTimerThreadAwake = 1; rtp_sig_semaphore_signal(rtpTimerSignal); } break; } rtp_sig_mutex_release(rtpTimerLock); return (result); }
/** @memo SSDP server initialization routine. @doc This routine starts up SSDP services by creating a UDP socket, getting the ssdp multicast membership for the socket and initlializing ssdp context. @return error code */ SSDP_INT32 SSDP_ServerInit( SSDPServerContext *ctx, /** pointer to an uninitialized SSDP context structure */ SSDP_UINT8 *ipAddr, /** IP address of the host to bind the UDP socket to, if a NULL is supplied, the UDP socket is bound to the local IP address */ SSDP_INT16 ipType, /** ip version 4 or ipversion 6 */ const SSDP_CHAR *serverId, /** String holding platform name */ SSDPCallback cb, /** SSDP Callback routine */ void *cookie /** cookie(runtime) to be stored in ssdp context to be passed later to ssdp callback */) { RTP_HANDLE ssdpSock; SSDP_INT32 ttl; unsigned char localAddr[RTP_NET_NI_MAXHOST]; unsigned char mcastAddr[RTP_NET_NI_MAXHOST]; /* * Open a datagram sockets used */ if (rtp_net_socket_datagram_dual (&ssdpSock, ipType) < 0) { SSDP_ProcessError("Datagram UDP socket"); return(-1); } /* Allow the socket to be bound to an address that is already in use. */ if (rtp_net_setreuseaddr (ssdpSock, 1) < 0) { SSDP_ProcessError("Socket reuse option"); return(-1); } if(ipType == RTP_NET_TYPE_IPV6) { rtp_strcpy((char *) mcastAddr, IPV6_LINK_LOCAL_ADDRESS); ttl = 255; } else if (ipType == RTP_NET_TYPE_IPV4) { rtp_strcpy((char *) mcastAddr,(const char *) v4mcastAddr); ttl = 4; } /* If ipaddress to bind to is not supplied, bind it to the local ip address */ if (!ipAddr) { /* obtain ipaddress on the current interface, localAddr will contains ipaddress of the interface */ if (rtp_net_getifaceaddr (localAddr, mcastAddr, mcastPort, ipType) < 0) { SSDP_ProcessError("error obtaining address"); } } else { rtp_strcpy((char *) localAddr, (const char *) ipAddr); } if (rtp_net_bind_dual (ssdpSock, RTP_NET_DATAGRAM, localAddr, mcastPort, ipType) < 0) { SSDP_ProcessError("Binding"); return(-1); } /* join the socket to multicast group */ if (rtp_net_setmembership(ssdpSock, mcastAddr, ipType, 1) < 0) { SSDP_ProcessError("Multicast Socket Option"); return(-1); } /* Sets the TTL value associated with multicast traffic on the socket */ if (rtp_net_setmcastttl(ssdpSock, ttl) < 0) { SSDP_ProcessError("Multicast TTL Option"); return(-1); } ctx->announceSocket = ssdpSock; ctx->userCallback = cb; ctx->userCookie = cookie; ctx->ipType = ipType; ctx->serverName = rtp_strdup(serverId); DLLIST_INIT(&ctx->pendingResponses); return(0); }
int HTTP_ServerInit (HTTPServerContext *server, /** pointer to uninitialized \Ref{HTTPServerContext} struct */ const HTTP_CHAR *name, /** Server name. Sent in HTTP header. */ const HTTP_CHAR *rootDir, /** Path to the root directory for content. */ const HTTP_CHAR *defaultFile, /** Default Filename if "\" or "path\" is passed with no file name. */ HTTP_INT8 httpMajorVersion, /** Normally 1 for HTTP 1.1 */ HTTP_INT8 httpMinorVersion, /** Normally 1 for HTTP 1.1 */ HTTP_UINT8 *ipAddr, /** V4/V6 examples: ipaddr[4] = {192, 168, 0, 6}; ipAddr = "fe80::20b:dbff:fe2f:c162"; */ HTTP_INT16 port, /** port number (80) usually */ HTTP_INT16 ipType, /** ipversion 4 or 6 */ HTTP_BOOL allowKeepAlive, /** If HTTP version < 1.1 enables keep-alive support. For 1,1 and greater keep-alive is the default.*/ HTTPServerConnection* connectCtxArray, /** pointer to uninitialized bytes, must be (sizeof(HTTPServerConnection) * maxConnections)) bytes. */ HTTP_INT16 maxConnections, /** The maximum limit on simultaneous HTTP server connections */ HTTP_INT16 maxHelperThreads /** If HTTP_SERVER_MULTITHREAD is defined, the max number of helper threads to spawn */ ) { rtp_memset((unsigned char *) server, 0, sizeof(HTTPServerContext)); if (rtp_net_socket_stream_dual(&server->serverSocket, ipType) >= 0) { if (rtp_net_bind_dual(server->serverSocket, RTP_NET_STREAM, ipAddr, port, ipType) >= 0 && rtp_net_listen(server->serverSocket, maxConnections) >= 0) { if (!ipAddr) { if (rtp_net_getsockname(server->serverSocket, server->serverAddress.ipAddr, &server->serverAddress.port, &server->serverAddress.type) < 0) { rtp_memset(server->serverAddress.ipAddr, 0, RTP_NET_IP_ALEN); } } else { rtp_memcpy(server->serverAddress.ipAddr, ipAddr, RTP_NET_IP_ALEN); server->serverAddress.port = port; } if (name) { rtp_strncpy(server->serverName, name, HTTP_SERVER_NAME_LEN-1); } else { rtp_strncpy(server->serverName, HTTP_SERVER_NAME_STRING, HTTP_SERVER_NAME_LEN-1); } server->httpMajorVersion = httpMajorVersion; server->httpMinorVersion = httpMinorVersion; if (rootDir) { rtp_strncpy(server->rootDir, rootDir, HTTP_SERVER_PATH_LEN-1); } else { /* default to the current working directory */ server->rootDir[0] = '.'; server->rootDir[1] = 0; } if (defaultFile) { rtp_strncpy(server->defaultFile, defaultFile, HTTP_SERVER_DEFAULT_FILE_LEN-1); } else { rtp_strncpy(server->defaultFile, HTTP_SERVER_DEFAULT_FILE, HTTP_SERVER_DEFAULT_FILE_LEN-1); } if (!allowKeepAlive || (server->httpMajorVersion == 1 && server->httpMinorVersion > 0) || (server->httpMajorVersion > 1)) { server->allowKeepAlive = allowKeepAlive; server->maxConnections = maxConnections; DLLIST_INIT(&server->pathList); DLLIST_INIT(&server->realmList); server->allowedClientList = 0; server->numAllowedClients = 0; server->blockedClientList = 0; server->numBlockedClients = 0; #ifdef HTTP_SERVER_KEEP_ALIVE DLLIST_INIT(&server->openConnections); #endif /* HTTP_SERVER_KEEP_ALIVE */ #ifdef HTTP_SERVER_MULTITHREAD server->connectionContextArray = connectCtxArray; server->maxHelperThreads = maxHelperThreads; /* allocate the server lock */ if (rtp_sig_mutex_alloc(&server->lock, 0) >= 0) { RTP_MUTEX helperThreadMutex; RTP_SEMAPHORE helperThreadSemaphore; /* initialize the session queue */ if (rtp_sig_mutex_alloc(&helperThreadMutex, 0) >= 0) { if (rtp_sig_semaphore_alloc(&helperThreadSemaphore, 0) >= 0) { if (rtp_helper_thread_ctx_init ( &server->helperContext, helperThreadMutex, helperThreadSemaphore ) >= 0) { int n; // initialize the free job list server->jobFreeList = connectCtxArray; for (n = 0; n < maxConnections-1; n++) { connectCtxArray[n].job.next = &(connectCtxArray[n+1].job); connectCtxArray[n].job.execute = _HTTP_ServerExecuteJob; connectCtxArray[n].server = server; } connectCtxArray[n].job.next = 0; connectCtxArray[n].job.execute = _HTTP_ServerExecuteJob; connectCtxArray[n].server = server; server->status = HTTP_SERVER_INITIALIZED; return (0); } rtp_sig_semaphore_free(helperThreadSemaphore); } rtp_sig_mutex_free(helperThreadMutex); } rtp_sig_mutex_free(server->lock); } #else /* HTTP_SERVER_MULTITHREAD */ //server->queueFirst = 0; //server->queueLast = 0; server->status = HTTP_SERVER_INITIALIZED; return (0); #endif /* HTTP_SERVER_MULTITHREAD */ } } rtp_net_closesocket(server->serverSocket); } return (-1); }