示例#1
0
文件: sock.c 项目: AriZuu/picoos-net
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;
}
示例#2
0
文件: sock.c 项目: AriZuu/picoos-net
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;
}
示例#3
0
文件: sock.c 项目: AriZuu/picoos-net
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);
}
示例#4
0
文件: sock.c 项目: AriZuu/picoos-net
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;
}
示例#5
0
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);
    }
}
示例#6
0
文件: ex_mutx1.c 项目: AriZuu/picoos
/* 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);
}
示例#7
0
文件: sock.c 项目: AriZuu/picoos-net
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;
}
示例#8
0
文件: sock.c 项目: AriZuu/picoos-net
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);
}
示例#9
0
文件: sock.c 项目: AriZuu/picoos-net
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);
    }
  }
}
示例#10
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);
    }
}
示例#11
0
文件: sock.c 项目: AriZuu/picoos-net
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();

  }
}
示例#12
0
文件: sock.c 项目: AriZuu/picoos-net
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);
    }
  }
}
示例#13
0
文件: sock.c 项目: AriZuu/picoos-net
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);
}
示例#14
0
文件: sock.c 项目: AriZuu/picoos-net
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;
}
示例#15
0
文件: httpd.c 项目: AriZuu/sensor-web
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;
}