UosFile* netSockAccept(UosFile* listenSockFile, uip_ipaddr_t* peer) { UosFile* file; P_ASSERT("netSockAccept", listenSockFile->fs->cf == &netFSConf); NetSock* listenSock = (NetSock*)listenSockFile->fsPriv; posMutexLock(listenSock->mutex); P_ASSERT("sockAccept", listenSock->state == NET_SOCK_LISTENING); listenSock->state = NET_SOCK_ACCEPTING; posFlagSet(listenSock->sockChange, 0); while (listenSock->state == NET_SOCK_ACCEPTING) { posMutexUnlock(listenSock->mutex); posFlagGet(listenSock->uipChange, POSFLAG_MODE_GETMASK); posMutexLock(listenSock->mutex); } P_ASSERT("sockAccept", listenSock->state == NET_SOCK_ACCEPTED); uip_ipaddr_copy(peer, &listenSock->newConnection->ripaddr); file = listenSock->newConnection->appstate.file; listenSock->newConnection = NULL; listenSock->state = NET_SOCK_LISTENING; posMutexUnlock(listenSock->mutex); return file; }
static int sockReadInternal(NetSock* sock, NetSockState state, void* data, uint16_t max, uint16_t timeout) { int len; bool timedOut = false; posMutexLock(sock->mutex); if (sock->state == NET_SOCK_PEER_CLOSED) { posMutexUnlock(sock->mutex); return NET_SOCK_EOF; } if (sock->state == NET_SOCK_PEER_ABORTED) { posMutexUnlock(sock->mutex); return NET_SOCK_ABORT; } P_ASSERT("sockRead", sock->state == NET_SOCK_BUSY); sock->state = state; sock->buf = data; sock->max = max; sock->len = 0; posFlagSet(sock->sockChange, 0); while (sock->state == state && !timedOut) { posMutexUnlock(sock->mutex); timedOut = posFlagWait(sock->uipChange, timeout) == 0; posMutexLock(sock->mutex); } if (sock->state == NET_SOCK_PEER_CLOSED) len = NET_SOCK_EOF; else if (sock->state == NET_SOCK_PEER_ABORTED) len = NET_SOCK_ABORT; else { P_ASSERT("sockRead", (timedOut && sock->state == state) || sock->state == NET_SOCK_READ_OK); if (timedOut && sock->state == state) len = NET_SOCK_TIMEOUT; else len = sock->len; sock->state = NET_SOCK_BUSY; } posMutexUnlock(sock->mutex); return len; }
void netSockListen(UosFile* file) { P_ASSERT("netSockListen", file->fs->cf == &netFSConf); NetSock* sock = (NetSock*)file->fsPriv; posMutexLock(sock->mutex); sock->state = NET_SOCK_LISTENING; posMutexUnlock(sock->mutex); posMutexLock(uipMutex); uip_listen(sock->port); posMutexUnlock(uipMutex); }
static int sockWrite(UosFile* file, const char* data, int len) { P_ASSERT("sockWrite", file->fs->cf == &netFSConf); NetSock* sock = (NetSock*)file->fsPriv; posMutexLock(sock->mutex); if (sock->state == NET_SOCK_PEER_CLOSED) { posMutexUnlock(sock->mutex); return NET_SOCK_EOF; } if (sock->state == NET_SOCK_PEER_ABORTED) { posMutexUnlock(sock->mutex); return NET_SOCK_ABORT; } P_ASSERT("sockWrite", sock->state == NET_SOCK_BUSY); sock->state = NET_SOCK_WRITING; sock->buf = (void*)data; sock->len = len; dataToSend = 1; posSemaSignal(uipGiant); while (sock->state == NET_SOCK_WRITING) { posMutexUnlock(sock->mutex); posFlagGet(sock->uipChange, POSFLAG_MODE_GETMASK); posMutexLock(sock->mutex); } if (sock->state == NET_SOCK_PEER_CLOSED) len = NET_SOCK_EOF; else if (sock->state == NET_SOCK_PEER_ABORTED) len = NET_SOCK_ABORT; else { P_ASSERT("sockWrite", sock->state == NET_SOCK_WRITE_OK); sock->state = NET_SOCK_BUSY; } posMutexUnlock(sock->mutex); return len; }
static void task_mutex(void *arg) { static INT_t cntr = 0; char *text = (char*) arg; for (;;) { /* try to get mutex and lock */ posMutexLock(mutex_g); cntr++; /* sleep one second */ posTaskSleep(HZ); /* print text */ print(text); cntr--; if (cntr != 0) print("MUTEX-ERROR"); /* unlock mutex again */ posMutexUnlock(mutex_g); } }
/* This function is called from two tasks. * It increments and prints a global counter variable. * The function uses a mutex to protect the shared variable, * so only one task is allowed to modify the variable at the time. */ void incrementCounter(int tasknbr) { int c; /* wait for exclusive access to counter variable */ posMutexLock(mutex); /* load variable */ c = counter; /* change copy of variable */ c++; /* waste some time */ posTaskSleep(MS(800)); /* store changed variable */ counter = c; /* print some text */ nosPrintf("task%i: counter = %i\n", tasknbr, counter); /* quit exclusive access to the counter variable */ posMutexUnlock(mutex); }
static int sockClose(UosFile* file) { P_ASSERT("sockWrite", file->fs->cf == &netFSConf); NetSock* sock = (NetSock*)file->fsPriv; posMutexLock(sock->mutex); if (sock->state == NET_SOCK_BUSY) { sock->state = NET_SOCK_CLOSE; dataToSend = 1; posSemaSignal(uipGiant); while (sock->state == NET_SOCK_CLOSE) { posMutexUnlock(sock->mutex); posFlagGet(sock->uipChange, POSFLAG_MODE_GETMASK); posMutexLock(sock->mutex); } } if (sock->state == NET_SOCK_LISTENING) { posMutexLock(uipMutex); uip_unlisten(sock->port); posMutexUnlock(uipMutex); sock->port = 0; sock->state = NET_SOCK_CLOSE_OK; } P_ASSERT("CloseState", (sock->state == NET_SOCK_PEER_CLOSED || sock->state == NET_SOCK_PEER_ABORTED || sock->state == NET_SOCK_CLOSE_OK)); netSockFree(file); return 0; }
void netUdpAppcall() { UosFile *file; file = uip_udp_conn->appstate.file; P_ASSERT("netUdpAppcall", file->fs->cf == &netFSConf); NetSock* sock = (NetSock*)file->fsPriv; if (sock->mutex == NULL) { return; } posMutexLock(sock->mutex); netUdpAppcallMutex(sock); if (sock->mutex != NULL) posMutexUnlock(sock->mutex); }
static void netUdpAppcallMutex(NetSock* sock) { if (uip_newdata()) { bool timeout = false; while (sock->state != NET_SOCK_READING && !timeout) { posMutexUnlock(sock->mutex); timeout = posFlagWait(sock->sockChange, MS(500)) == 0; posMutexLock(sock->mutex); } if (!timeout) { if (uip_datalen() > sock->max) sock->len = sock->max; else sock->len = uip_datalen(); memcpy(sock->buf, uip_appdata, sock->len); sock->state = NET_SOCK_READ_OK; posFlagSet(sock->uipChange, 0); } } if (uip_poll()) { if (sock->state == NET_SOCK_CLOSE) { uip_udp_remove(uip_udp_conn); netAppcallClose(sock, NET_SOCK_CLOSE_OK); } else if (sock->state == NET_SOCK_WRITING) { memcpy(uip_appdata, sock->buf, sock->len); uip_udp_send(sock->len); sock->state = NET_SOCK_WRITE_OK; posFlagSet(sock->uipChange, 0); } } }
/* * This task will be start three times. Each task increments * ten times the global variable summe. */ static void workerTask(void *arg) { uint8_t i; for (i=0; i < 10; i++) { // get the mutex posMutexLock(mutex); uint8_t localSumme = summe; posTaskSleep(HZ/1000); localSumme++; summe = localSumme; // unlock mutex posMutexUnlock(mutex); } }
void netMainThread(void* arg) { uint8_t i; #if !NETSTACK_CONF_WITH_IPV6 POSTIMER_t arpTimer; #endif POSTIMER_t periodicTimer; int sendRequested; bool packetSeen; #if !NETSTACK_CONF_WITH_IPV6 arpTimer = posTimerCreate(); P_ASSERT("netMainThread1", arpTimer != NULL); posTimerSet(arpTimer, uipGiant, MS(10000), MS(10000)); posTimerStart(arpTimer); #endif periodicTimer = posTimerCreate(); P_ASSERT("netMainThread2", periodicTimer != NULL); posTimerSet(periodicTimer, uipGiant, MS(500), MS(500)); posTimerStart(periodicTimer); posMutexLock(uipMutex); packetSeen = false; while(1) { posMutexUnlock(uipMutex); // Using semaphore here is not fully optimal. // As it is a counting one, it can get bumped // to larger value than 1 by upper or interrupt // layer. However, not much harm is done, // this loop just spins extra times without // doing nothing useful. // A Pico]OS Flag object would be perfect, // but it doesn't work with posTimer* functions. if (!packetSeen || pollTicks == INFINITE) posSemaWait(uipGiant, pollTicks); posMutexLock(uipMutex); sendRequested = dataToSend; dataToSend = 0; packetSeen = false; if (sendRequested) { for(i = 0; i < UIP_CONNS; i++) { uip_len = 0; uip_poll_conn(&uip_conns[i]); if(uip_len > 0) { #if NETCFG_UIP_SPLIT == 1 uip_split_output(); #else #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else tcpip_output(); #endif #endif } } #if UIP_UDP for(i = 0; i < UIP_UDP_CONNS; i++) { uip_len = 0; uip_udp_periodic(i); if(uip_len > 0) { #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else tcpip_output(); #endif } } #endif /* UIP_UDP */ } packetSeen = netInterfacePoll(); if (posTimerFired(periodicTimer)) { for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); if(uip_len > 0) { #if NETCFG_UIP_SPLIT == 1 uip_split_output(); #else #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else tcpip_output(); #endif #endif } } #if UIP_UDP for(i = 0; i < UIP_UDP_CONNS; i++) { uip_udp_periodic(i); if(uip_len > 0) { #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else tcpip_output(); #endif } } #endif /* UIP_UDP */ } #if NETSTACK_CONF_WITH_IPV6 == 0 if (posTimerFired(arpTimer)) { uip_arp_timer(); } #endif // Run contiki-style timers. // Instead of posting events to process like // contiki does, it just calls common callback function // to do the work. etimer_request_poll(); } }
static void netTcpAppcallMutex(NetSock* sock) { if (uip_aborted()) { netAppcallClose(sock, NET_SOCK_PEER_ABORTED); } if (uip_timedout()) { netAppcallClose(sock, NET_SOCK_PEER_ABORTED); } if(uip_acked()) { if (sock->state == NET_SOCK_WRITING) { if (sock->len <= uip_mss()) { sock->len = 0; sock->state = NET_SOCK_WRITE_OK; posFlagSet(sock->uipChange, 0); } else { sock->buf = sock->buf + uip_mss(); sock->len -= uip_mss(); uip_send(sock->buf, sock->len); } } } if (uip_newdata()) { bool timeout = false; uint16_t dataLeft = uip_datalen(); char* dataPtr = uip_appdata; while (dataLeft > 0 && !timeout) { while (sock->state != NET_SOCK_READING && sock->state != NET_SOCK_READING_LINE && !timeout) { posMutexUnlock(sock->mutex); timeout = posFlagWait(sock->sockChange, MS(500)) == 0; posMutexLock(sock->mutex); } if (timeout) { // Timeout or bad state uip_abort(); netAppcallClose(sock, NET_SOCK_PEER_ABORTED); } else if (sock->state == NET_SOCK_READING_LINE) { char ch; while (dataLeft && sock->len < sock->max) { ch = *dataPtr; if (ch == '\r') { ++dataPtr; --dataLeft; continue; } sock->buf[sock->len] = ch; ++dataPtr; --dataLeft; ++sock->len; if (ch == '\n') break; } if (sock->len && (sock->len == sock->max || sock->buf[sock->len - 1] == '\n')) { sock->state = NET_SOCK_READ_OK; posFlagSet(sock->uipChange, 0); } } else if (sock->state == NET_SOCK_READING) { if (dataLeft > sock->max) sock->len = sock->max; else sock->len = dataLeft; memcpy(sock->buf, dataPtr, sock->len); dataLeft -= sock->len; dataPtr += sock->len; sock->state = NET_SOCK_READ_OK; posFlagSet(sock->uipChange, 0); } } } if (uip_rexmit()) { uip_send(sock->buf, sock->len); } if (uip_closed()) { netAppcallClose(sock, NET_SOCK_PEER_CLOSED); } if (uip_poll()) { if (sock->state == NET_SOCK_CLOSE) { uip_close(); netAppcallClose(sock, NET_SOCK_CLOSE_OK); } else if (sock->state == NET_SOCK_WRITING) { uip_send(sock->buf, sock->len); } } }
void netTcpAppcall() { UosFile *file = NULL; if (uip_connected()) { if (uip_conn->appstate.file == NULL) { if (acceptHook != NULL) { file = netSockAlloc(NET_SOCK_BUSY); if (file == NULL) { uip_abort(); return; } uip_conn->appstate.file = file; if ((*acceptHook)(file, uip_ntohs(uip_conn->lport)) == -1) { netSockFree(file); uip_conn->appstate.file = NULL; uip_abort(); return; } } else { int i; NetSock* listenSock; for (i = 0; i < SOCK_TABSIZE; i++, listenSock++) { if (UOS_BITTAB_IS_FREE(netSocketTable, i)) continue; listenSock = UOS_BITTAB_ELEM(netSocketTable, i); if ((listenSock->state == NET_SOCK_LISTENING || listenSock->state == NET_SOCK_ACCEPTING || listenSock->state == NET_SOCK_ACCEPTED) && listenSock->port == uip_conn->lport) break; } if (i >= SOCK_TABSIZE) { uip_abort(); return; } bool timeout = false; posMutexLock(listenSock->mutex); while (listenSock->state != NET_SOCK_ACCEPTING && !timeout) { posMutexUnlock(listenSock->mutex); timeout = posFlagWait(listenSock->sockChange, MS(200)) == 0; posMutexLock(listenSock->mutex); } if (timeout) { uip_abort(); posMutexUnlock(listenSock->mutex); return; } file = netSockAlloc(NET_SOCK_BUSY); if (file == NULL) { uip_abort(); posMutexUnlock(listenSock->mutex); return; } uip_conn->appstate.file = file; listenSock->newConnection = uip_conn; listenSock->state = NET_SOCK_ACCEPTED; posFlagSet(listenSock->uipChange, 0); posMutexUnlock(listenSock->mutex); } } else { file = uip_conn->appstate.file; P_ASSERT("netTcpAppcall", file->fs->cf == &netFSConf); NetSock* sock = (NetSock*)file->fsPriv; if (sock->state == NET_SOCK_CONNECT) { posMutexLock(sock->mutex); sock->state = NET_SOCK_CONNECT_OK; posFlagSet(sock->uipChange, 1); posMutexUnlock(sock->mutex); } } } file = uip_conn->appstate.file; // Check if connection is related to socket. // If not, the socket has already been closed and // there is nothing more to do. if (file == NULL) return; P_ASSERT("netTcpAppcall", file->fs->cf == &netFSConf); NetSock* sock = (NetSock*)file->fsPriv; posMutexLock(sock->mutex); netTcpAppcallMutex(sock); if (sock->mutex != NULL) posMutexUnlock(sock->mutex); }
int netSockConnect(UosFile* file, uip_ipaddr_t* ip, int port) { struct uip_conn* tcp; struct uip_udp_conn* udp; P_ASSERT("netSockConnect", file->fs->cf == &netFSConf); NetSock* sock = (NetSock*)file->fsPriv; #if UIP_ACTIVE_OPEN == 1 P_ASSERT("sockConnect", (sock->state == NET_SOCK_UNDEF_TCP || sock->state == NET_SOCK_UNDEF_UDP || sock->state == NET_SOCK_BOUND || sock->state == NET_SOCK_BOUND_UDP)); #else P_ASSERT("sockConnect", (sock->state == NET_SOCK_UNDEF_UDP || NET_SOCK_BOUND_UDP)); #endif if (sock->state == NET_SOCK_UNDEF_TCP) { #if UIP_ACTIVE_OPEN == 1 posMutexLock(uipMutex); tcp = uip_connect(ip, uip_htons(port)); if (tcp == NULL) { posMutexUnlock(uipMutex); return -1; } tcp->appstate.file = file; posMutexLock(sock->mutex); sock->state = NET_SOCK_CONNECT; posMutexUnlock(uipMutex); while (sock->state == NET_SOCK_CONNECT) { posMutexUnlock(sock->mutex); posFlagGet(sock->uipChange, POSFLAG_MODE_GETMASK); posMutexLock(sock->mutex); } if (sock->state == NET_SOCK_PEER_CLOSED || sock->state == NET_SOCK_PEER_ABORTED) { posMutexUnlock(sock->mutex); uosFileClose(file); return -1; } P_ASSERT("sockConnect", sock->state == NET_SOCK_CONNECT_OK); sock->state = NET_SOCK_BUSY; #endif } else { #if UIP_CONF_UDP == 1 posMutexLock(uipMutex); udp = uip_udp_new(ip, uip_htons(port)); if (udp == NULL) { posMutexUnlock(uipMutex); return -1; } udp->appstate.file = file; if (sock->state == NET_SOCK_BOUND_UDP) uip_udp_bind(udp, sock->port); sock->state = NET_SOCK_BUSY; posMutexUnlock(uipMutex); #endif } return 0; }
static int serveCgi(UosFile* sock, char* url, char* buf) { char* ptr; int i; int j; bool first; Sensor* s = sensorData; char addr[30]; if (!strcmp(url, "/front_data.cgi")) { posMutexLock(sensorMutex); ptr = buf; for (i = 0; i < MAX_TEMP; i++) { if (i == 0) { strcpy(ptr, "["); ptr = ptr + 1; } sensorAddressStr(addr, s); nosSPrintf(ptr, "{\"sensor\":\"%s\"", addr); ptr += strlen(ptr); nosSPrintf(ptr, ",\"temp\":%d.%d", T2I(s->temp), T2D(s->temp)); ptr += strlen(ptr); nosSPrintf(ptr, ",\"tempMin\":%d.%d", T2I(s->tempMin), T2D(s->tempMin)); ptr += strlen(ptr); nosSPrintf(ptr, ",\"tempMax\":%d.%d", T2I(s->tempMax), T2D(s->tempMax)); ptr += strlen(ptr); strcpy(ptr, ",\"tempHistory\":["); ptr += strlen(ptr); j = s->tempCount - 5; if (j < 0) j = 0; first = true; for (;j < s->tempCount; j++) { if (!first) { *ptr = ','; ++ptr; } first = false; nosSPrintf(ptr, "%d.%d", T2I(s->temps[j]), T2D(s->temps[j])); ptr += strlen(ptr); } strcpy(ptr, "]}"); ptr += strlen(ptr); if (i == MAX_TEMP - 1 || s[1].serialNum[0] == 0) { strcat(ptr, "]"); ptr += 1; uosFileWrite(sock, buf, ptr - buf); break; } else { strcat(ptr, ","); ptr += 1; if (SOCK_BUF_SIZE - (ptr - buf) < 128) { uosFileWrite(sock, buf, ptr - buf); ptr = buf; } } s++; } posMutexUnlock(sensorMutex); } else if (!strcmp(url, "/temp_trend_data.cgi")) { posMutexLock(sensorMutex); sensorAddressStr(addr, s); ptr = buf; for (i = 0; i < s->tempCount; i++) { if (i == 0) { strcpy(ptr, "["); ptr = ptr + 1; } nosSPrintf(ptr, "{\"sensor\":\"%s\",\"timeStamp\":%d,\"temp\":%d.%d}", addr, i - s->tempCount + 1, T2I(s->temps[i]), T2D(s->temps[i])); ptr += strlen(ptr); if (i == s->tempCount - 1) { strcat(ptr, "]"); ptr += 1; uosFileWrite(sock, buf, ptr - buf); } else { strcat(ptr, ","); ptr += 1; if (SOCK_BUF_SIZE - (ptr - buf) < 128) { uosFileWrite(sock, buf, ptr - buf); ptr = buf; } } } posMutexUnlock(sensorMutex); } else uosFileWrite(sock, "No-No", 5); return 0; }