Example #1
0
/**
 * Wait (forever) for a message to arrive in an mbox.
 * While waiting, timeouts (for this thread) are processed.
 *
 * @param mbox the mbox to fetch the message from
 * @param msg the place to store the message
 */
void
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
{
  u32_t time_needed;
  struct sys_timeouts *timeouts;
  struct sys_timeo *tmptimeout;
  sys_timeout_handler h;
  void *arg;

 again:
  timeouts = sys_arch_timeouts();

  if (!timeouts || !timeouts->next) {
    UNLOCK_TCPIP_CORE();
    time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
    LOCK_TCPIP_CORE();
  } else {
    if (timeouts->next->time > 0) {
      UNLOCK_TCPIP_CORE();
      time_needed = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
      LOCK_TCPIP_CORE();
    } else {
      time_needed = SYS_ARCH_TIMEOUT;
    }

    if (time_needed == SYS_ARCH_TIMEOUT) {
      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
         could be fetched. We should now call the timeout handler and
         deallocate the memory allocated for the timeout. */
      tmptimeout = timeouts->next;
      timeouts->next = tmptimeout->next;
      h   = tmptimeout->h;
      arg = tmptimeout->arg;
      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
      if (h != NULL) {
        LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\r\n", *(void**)&h, arg));
        h(arg);
      }

      /* We try again to fetch a message from the mbox. */
      goto again;
    } else {
      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
         occured. The time variable is set to the number of
         milliseconds we waited for the message. */
      if (time_needed < timeouts->next->time) {
        timeouts->next->time -= time_needed;
      } else {
        timeouts->next->time = 0;
      }
    }
  }
}
Example #2
0
File: tcpip.c Project: wosayttn/aos
/**
 * Sends a message to TCPIP thread to call a function. Caller thread blocks on
 * on a provided semaphore, which ist NOT automatically signalled by TCPIP thread,
 * this has to be done by the user.
 * It is recommended to use LWIP_TCPIP_CORE_LOCKING since this is the way
 * with least runtime overhead.
 *
 * @param fn function to be called from TCPIP thread
 * @param apimsg argument to API function
 * @param sem semaphore to wait on
 * @return ERR_OK if the function was called, another err_t if not
 */
err_t
tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem)
{
#if LWIP_TCPIP_CORE_LOCKING
  LWIP_UNUSED_ARG(sem);
  LOCK_TCPIP_CORE();
  fn(apimsg);
  UNLOCK_TCPIP_CORE();
  return ERR_OK;
#else /* LWIP_TCPIP_CORE_LOCKING */
  TCPIP_MSG_VAR_DECLARE(msg);

  LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));

  TCPIP_MSG_VAR_ALLOC(msg);
  TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API;
  TCPIP_MSG_VAR_REF(msg).msg.api_msg.function = fn;
  TCPIP_MSG_VAR_REF(msg).msg.api_msg.msg = apimsg;
  sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg));
  sys_arch_sem_wait(sem, 0);
  TCPIP_MSG_VAR_FREE(msg);
  return ERR_OK;
#endif /* LWIP_TCPIP_CORE_LOCKING */
}
Example #3
0
/**
 * Send some data on a TCP pcb contained in a netconn
 * Called from netconn_write
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_write(struct api_msg_msg *msg)
{
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
#if LWIP_TCP
      msg->conn->state = NETCONN_WRITE;
      /* set all the variables used by do_writemore */
      LWIP_ASSERT("already writing", msg->conn->write_msg == NULL &&
        msg->conn->write_offset == 0);
      msg->conn->write_msg = msg;
      msg->conn->write_offset = 0;
#if LWIP_TCPIP_CORE_LOCKING
      msg->conn->write_delayed = 0;
      if (do_writemore(msg->conn) != ERR_OK) {
        LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
        UNLOCK_TCPIP_CORE();
        sys_arch_sem_wait(msg->conn->op_completed, 0);
        LOCK_TCPIP_CORE();
        LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
      }
#else
      do_writemore(msg->conn);
#endif
      /* for both cases: if do_writemore was called, don't ACK the APIMSG! */
      return;
#endif /* LWIP_TCP */
#if (LWIP_UDP || LWIP_RAW)
    } else {
      msg->conn->err = ERR_VAL;
#endif /* (LWIP_UDP || LWIP_RAW) */
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
Example #4
0
/**
 * Pass a received packet to tcpip_thread for input processing
 *
 * @param p the received packet, p->payload pointing to the Ethernet header or
 *          to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
 *          NETIF_FLAG_ETHERNET flags)
 * @param inp the network interface on which the packet was received
 */
err_t
tcpip_pppos_input(struct pbuf *p, struct netif *inp)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
  err_t ret;
  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_pppos_input: PACKET %p/%p\n", (void *)p, (void *)inp));
  LOCK_TCPIP_CORE();
  ret = pppos_input_sys(p, inp);
  UNLOCK_TCPIP_CORE();
  return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
  struct tcpip_msg *msg;

  if (!sys_mbox_valid_val(mbox)) {
    return ERR_VAL;
  }
  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
  if (msg == NULL) {
    return ERR_MEM;
  }

  msg->type = TCPIP_MSG_INPKT_PPPOS;
  msg->msg.inp.p = p;
  msg->msg.inp.netif = inp;
  if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
    memp_free(MEMP_TCPIP_MSG_INPKT, msg);
    return ERR_MEM;
  }
  return ERR_OK;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
}
Example #5
0
File: tcpip.c Project: wosayttn/aos
/**
 * Pass a received packet to tcpip_thread for input processing
 *
 * @param p the received packet
 * @param inp the network interface on which the packet was received
 * @param input_fn input function to call
 */
err_t
tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
  err_t ret;
  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));
  LOCK_TCPIP_CORE();
  ret = input_fn(p, inp);
  UNLOCK_TCPIP_CORE();
  return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
  struct tcpip_msg *msg;

  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));

  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
  if (msg == NULL) {
    return ERR_MEM;
  }

  msg->type = TCPIP_MSG_INPKT;
  msg->msg.inp.p = p;
  msg->msg.inp.netif = inp;
  msg->msg.inp.input_fn = input_fn;
  if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
    memp_free(MEMP_TCPIP_MSG_INPKT, msg);
    return ERR_MEM;
  }
  return ERR_OK;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
}
Example #6
0
/**
 * Call the lower part of a pppapi_* function
 * This function has exclusive access to lwIP core code by locking it
 * before the function is called.
 *
 * @param pppapimsg a struct containing the function to call and its parameters
 * @return ERR_OK (only for compatibility fo tcpip_pppapi())
 */
err_t
tcpip_pppapi_lock(struct pppapi_msg* pppapimsg)
{
  LOCK_TCPIP_CORE();
  pppapimsg->function(&(pppapimsg->msg));
  UNLOCK_TCPIP_CORE();
  return pppapimsg->msg.err;
}
Example #7
0
/**
 * Call the lower part of a netifapi_* function
 * This function has exclusive access to lwIP core code by locking it
 * before the function is called.
 *
 * @param netifapimsg a struct containing the function to call and its parameters
 * @return ERR_OK (only for compatibility fo tcpip_netifapi())
 */
err_t
tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
{
  LOCK_TCPIP_CORE();  
  netifapimsg->function(&(netifapimsg->msg));
  UNLOCK_TCPIP_CORE();
  return netifapimsg->msg.err;
}
Example #8
0
/**
 * Call the lower part of a netifapi_* function
 * This function has exclusive access to lwIP core code by locking it
 * before the function is called.
 *
 * @param netifapimsg a struct containing the function to call and its parameters
 * @return ERR_OK (only for compatibility fo tcpip_netifapi())
 */
static err_t
tcpip_netifapi_lock(tcpip_callback_fn fn, struct netifapi_msg* netifapimsg)
{
  LOCK_TCPIP_CORE();
  fn(netifapimsg);
  UNLOCK_TCPIP_CORE();
  return netifapimsg->err;
}
Example #9
0
/**
 * Wait (forever) for a message to arrive in an mbox.
 * While waiting, timeouts are processed.
 *
 * @param mbox the mbox to fetch the message from
 * @param msg the place to store the message
 */
void
sys_timeouts_mbox_fetch_p(u8 timeo_assigned, sys_mbox_t mbox, void **msg)
{
  u32_t time_needed;
  struct sys_timeo *tmptimeout;
  sys_timeout_handler handler;
  void *arg;

  struct sys_timeo **timeo = &next_timeout[timeo_assigned];
  
 again:
  if (!(*timeo)) {
    time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
  } else {
    if ((*timeo)->time > 0) {
      time_needed = sys_arch_mbox_fetch(mbox, msg, (*timeo)->time);
    } else {
      time_needed = SYS_ARCH_TIMEOUT;
    }

    if (time_needed == SYS_ARCH_TIMEOUT) {
      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
         could be fetched. We should now call the timeout handler and
         deallocate the memory allocated for the timeout. */
      tmptimeout = *timeo;
      *timeo = tmptimeout->next;
      handler = tmptimeout->h;
      arg = tmptimeout->arg;
#if LWIP_DEBUG_TIMERNAMES
      if (handler != NULL) {
        LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n",
          tmptimeout->handler_name, arg));
      }
#endif /* LWIP_DEBUG_TIMERNAMES */
      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
      if (handler != NULL) {
        /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the
           timeout handler function. */
        LOCK_TCPIP_CORE();
        handler(arg);
        UNLOCK_TCPIP_CORE();
      }
      LWIP_TCPIP_THREAD_ALIVE();

      /* We try again to fetch a message from the mbox. */
      goto again;
    } else {
      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
         occured. The time variable is set to the number of
         milliseconds we waited for the message. */
      if (time_needed < (*timeo)->time) {
        (*timeo)->time -= time_needed;
      } else {
        (*timeo)->time = 0;
      }
    }
  }
}
Example #10
0
/**
 * Call the lower part of a netconn_* function
 * This function has exclusive access to lwIP core code by locking it
 * before the function is called.
 *
 * @param apimsg a struct containing the function to call and its parameters
 * @return ERR_OK (only for compatibility fo tcpip_apimsg())
 */
err_t
tcpip_apimsg_lock(struct api_msg *apimsg)
{
  LOCK_TCPIP_CORE();
  apimsg->function(&(apimsg->msg));
  UNLOCK_TCPIP_CORE();
  return ERR_OK;

}
Example #11
0
void
snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg)
{
#if LWIP_TCPIP_CORE_LOCKING
  LOCK_TCPIP_CORE();
  fn(arg);
  UNLOCK_TCPIP_CORE();
#else
  tcpip_callback_with_block(fn, arg, 1);
#endif
}
Example #12
0
static
#endif /* !NO_SYS */
void
sys_check_timeouts(void)
{
  if (next_timeout) {
    struct sys_timeo *tmptimeout;
    u32_t diff;
    sys_timeout_handler handler;
    void *arg;
    u8_t had_one;
    u32_t now;

    now = sys_now();
    /* this cares for wraparounds */
    diff = now - timeouts_last_time;
    do {
      PBUF_CHECK_FREE_OOSEQ();
      had_one = 0;
      tmptimeout = next_timeout;
      if (tmptimeout && (tmptimeout->time <= diff)) {
        /* timeout has expired */
        had_one = 1;
        timeouts_last_time += tmptimeout->time;
        diff -= tmptimeout->time;
        next_timeout = tmptimeout->next;
        handler = tmptimeout->h;
        arg = tmptimeout->arg;
#if LWIP_DEBUG_TIMERNAMES
        if (handler != NULL) {
          LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n",
            tmptimeout->handler_name, arg));
        }
#endif /* LWIP_DEBUG_TIMERNAMES */
        memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
        if (handler != NULL) {
#if !NO_SYS
          /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the
             timeout handler function. */
          LOCK_TCPIP_CORE();
#endif /* !NO_SYS */
          handler(arg);
#if !NO_SYS
          UNLOCK_TCPIP_CORE();
#endif /* !NO_SYS */
        }
        LWIP_TCPIP_THREAD_ALIVE();
      }
    /* repeat until all expired timers have been called */
    } while (had_one);
  }
}
Example #13
0
/**
 * Call the lower part of a netconn_* function
 * This function has exclusive access to lwIP core code by locking it
 * before the function is called.
 *
 * @param apimsg a struct containing the function to call and its parameters
 * @return ERR_OK (only for compatibility fo tcpip_apimsg())
 */
err_t
tcpip_apimsg_lock(struct api_msg *apimsg)
{
#ifdef LWIP_DEBUG
  /* catch functions that don't set err */
  apimsg->msg.err = ERR_VAL;
#endif

  LOCK_TCPIP_CORE();
  apimsg->function(&(apimsg->msg));
  UNLOCK_TCPIP_CORE();
  return apimsg->msg.err;

}
Example #14
0
/**
 * Send some data on a TCP pcb contained in a netconn
 * Called from netconn_write
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_write(struct api_msg_msg *msg)
{
    if (ERR_IS_FATAL(msg->conn->last_err)) {
        msg->err = msg->conn->last_err;
    } else {
        if (msg->conn->type == NETCONN_TCP) {
#if LWIP_TCP
            if (msg->conn->state != NETCONN_NONE) {
                /* netconn is connecting, closing or in blocking write */
                msg->err = ERR_INPROGRESS;
            } else if (msg->conn->pcb.tcp != NULL) {
                msg->conn->state = NETCONN_WRITE;
                /* set all the variables used by do_writemore */
                LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
                            msg->conn->write_offset == 0);
                LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0);
                msg->conn->current_msg = msg;
                msg->conn->write_offset = 0;
#if LWIP_TCPIP_CORE_LOCKING
                msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
                if (do_writemore(msg->conn) != ERR_OK) {
                    LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
                    UNLOCK_TCPIP_CORE();
                    sys_arch_sem_wait(&msg->conn->op_completed, 0);
                    LOCK_TCPIP_CORE();
                    LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
                }
#else /* LWIP_TCPIP_CORE_LOCKING */
                do_writemore(msg->conn);
#endif /* LWIP_TCPIP_CORE_LOCKING */
                /* for both cases: if do_writemore was called, don't ACK the APIMSG
                   since do_writemore ACKs it! */
                return;
            } else {
                msg->err = ERR_CONN;
            }
#else /* LWIP_TCP */
            msg->err = ERR_VAL;
#endif /* LWIP_TCP */
#if (LWIP_UDP || LWIP_RAW)
        } else {
            msg->err = ERR_VAL;
#endif /* (LWIP_UDP || LWIP_RAW) */
        }
    }
    TCPIP_APIMSG_ACK(msg);
}
Example #15
0
File: tcpip.c Project: wosayttn/aos
/**
 * Synchronously calls function in TCPIP thread and waits for its completion.
 * It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or
 * LWIP_NETCONN_SEM_PER_THREAD. 
 * If not, a semaphore is created and destroyed on every call which is usually
 * an expensive/slow operation.
 * @param fn Function to call
 * @param call Call parameters
 * @return Return value from tcpip_api_call_fn
 */
err_t
tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
{
#if LWIP_TCPIP_CORE_LOCKING
  err_t err;
  LOCK_TCPIP_CORE();
  err = fn(call);
  UNLOCK_TCPIP_CORE();
  return err;
#else /* LWIP_TCPIP_CORE_LOCKING */
  TCPIP_MSG_VAR_DECLARE(msg);

#if !LWIP_NETCONN_SEM_PER_THREAD
  err_t err = sys_sem_new(&call->sem, 0);
  if (err != ERR_OK) {
    return err;
  }
#endif /* LWIP_NETCONN_SEM_PER_THREAD */

  LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox));

  TCPIP_MSG_VAR_ALLOC(msg);
  TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API_CALL;
  TCPIP_MSG_VAR_REF(msg).msg.api_call.arg = call;
  TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn;
#if LWIP_NETCONN_SEM_PER_THREAD
  TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET();
#else /* LWIP_NETCONN_SEM_PER_THREAD */
  TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem;
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
  sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg));
  sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0);
  TCPIP_MSG_VAR_FREE(msg);

#if !LWIP_NETCONN_SEM_PER_THREAD
  sys_sem_free(&call->sem);
#endif /* LWIP_NETCONN_SEM_PER_THREAD */

  return call->err;
#endif /* LWIP_TCPIP_CORE_LOCKING */
}
Example #16
0
/**
 * Pass a received packet to tcpip_thread for input processing
 *
 * @param p the received packet, p->payload pointing to the Ethernet header or
 *          to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
 *          NETIF_FLAG_ETHERNET flags)
 * @param inp the network interface on which the packet was received
 */
err_t
tcpip_input(struct pbuf *p, struct netif *inp)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
  err_t ret;
  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
  LOCK_TCPIP_CORE();
#if LWIP_ETHERNET
  if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
    ret = ethernet_input(p, inp);
  } else
#endif /* LWIP_ETHERNET */
  {
    ret = ip_input(p, inp);
  }
  UNLOCK_TCPIP_CORE();
  return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
  struct tcpip_msg *msg;

  if (sys_mbox_valid(&mbox)) {
    msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
    if (msg == NULL) {
      return ERR_MEM;
    }

    msg->type = TCPIP_MSG_INPKT;
#ifdef __ADSPBLACKFIN__
    msg->flags = 0;
#endif
    msg->msg.inp.p = p;
    msg->msg.inp.netif = inp;
    if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
      return ERR_MEM;
    }
    return ERR_OK;
  }
  return ERR_VAL;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
}
Example #17
0
/*********************************************************************************************************
** 函数名称: __rtSafeRun
** 功能描述: 安全的运行一个回调函数, 不能破坏协议栈
** 输 入  : pfuncHook     执行函数
**           pvArg0...5    参数
** 输 出  : 执行结果
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static INT __rtSafeRun (FUNCPTR  pfuncHook,
                        PVOID    pvArg0,
                        PVOID    pvArg1,
                        PVOID    pvArg2,
                        PVOID    pvArg3,
                        PVOID    pvArg4,
                        PVOID    pvArg5)
{
#if LWIP_TCPIP_CORE_LOCKING < 1
#error sylixos need LWIP_TCPIP_CORE_LOCKING > 0
#endif                                                                  /*  LWIP_TCPIP_CORE_LOCKING     */

    INT     iError;

    if (sys_mutex_valid(&lock_tcpip_core)) {
        LOCK_TCPIP_CORE();
        iError = pfuncHook(pvArg0, pvArg1, pvArg2, pvArg3, pvArg4, pvArg5);
        UNLOCK_TCPIP_CORE();
    } else {
        iError = pfuncHook(pvArg0, pvArg1, pvArg2, pvArg3, pvArg4, pvArg5);
    }
    
    return  (iError);
}
Example #18
0
File: tcpip.c Project: wosayttn/aos
/**
 * The main lwIP thread. This thread has exclusive access to lwIP core functions
 * (unless access to them is not locked). Other threads communicate with this
 * thread using message boxes.
 *
 * It also starts all the timers to make sure they are running in the right
 * thread context.
 *
 * @param arg unused argument
 */
static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);

  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }

  LOCK_TCPIP_CORE();
  while (1) {                          /* MAIN Loop */
    UNLOCK_TCPIP_CORE();
    LWIP_TCPIP_THREAD_ALIVE();
    /* wait for a message, timeouts are processed while waiting */
    TCPIP_MBOX_FETCH(&mbox, (void **)&msg);
    LOCK_TCPIP_CORE();
    if (msg == NULL) {
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      continue;
    }
    switch (msg->type) {
#if !LWIP_TCPIP_CORE_LOCKING
    case TCPIP_MSG_API:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
      msg->msg.api_msg.function(msg->msg.api_msg.msg);
      break;
    case TCPIP_MSG_API_CALL:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg));
      msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg);
      sys_sem_signal(msg->msg.api_call.sem);
      break;
#endif /* !LWIP_TCPIP_CORE_LOCKING */

#if !LWIP_TCPIP_CORE_LOCKING_INPUT
    case TCPIP_MSG_INPKT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
      msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif);
      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
      break;
#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */

#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
    case TCPIP_MSG_TIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
    case TCPIP_MSG_UNTIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */

    case TCPIP_MSG_CALLBACK:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
      msg->msg.cb.function(msg->msg.cb.ctx);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

    case TCPIP_MSG_CALLBACK_STATIC:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
      msg->msg.cb.function(msg->msg.cb.ctx);
      break;
#ifdef LWIP_NETIF_DRV
    case TCPIP_MSG_DRV:
      LWIP_DEBUGF(NETIF_DEBUG, ("tcpip_thread: DRV %p\n", (void *)msg));
      msg->msg.drv.drv_fn(msg->msg.drv.netif, msg->msg.drv.event);
      memp_free(MEMP_NETIF_DRV_MSG, msg);
      break;
#endif
    default:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      break;
    }
  }
}
Example #19
0
/*********************************************************************************************************
** 函数名称: __tshellArp
** 功能描述: 系统命令 "arp"
** 输 入  : iArgC         参数个数
**           ppcArgV       参数表
** 输 出  : 0
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static INT  __tshellArp (INT  iArgC, PCHAR  *ppcArgV)
{
    if (iArgC < 2) {
        fprintf(stderr, "argments error!\n");
        return  (-ERROR_TSHELL_EPARAM);
    }
    
    if (lib_strcmp(ppcArgV[1], "-a") == 0) {                            /*  显示 arp 表                 */
        INT     iFd;
        CHAR    cBuffer[512];
        ssize_t sstNum;
        
        iFd = open("/proc/net/arp", O_RDONLY);
        if (iFd < 0) {
            fprintf(stderr, "can not open /proc/net/arp : %s\n", lib_strerror(errno));
            return  (PX_ERROR);
        }
        
        do {
            sstNum = read(iFd, cBuffer, sizeof(cBuffer));
            if (sstNum > 0) {
                write(STDOUT_FILENO, cBuffer, (size_t)sstNum);
            }
        } while (sstNum > 0);
        
        close(iFd);
        
        return  (ERROR_NONE);
    
    } else if (lib_strcmp(ppcArgV[1], "-s") == 0) {                     /*  加入一个静态转换关系        */
        INT             i;
        INT             iTemp[6];
        ip_addr_t       ipaddr;
        struct eth_addr ethaddr;
        err_t           err;
        
        if (iArgC != 4) {
            fprintf(stderr, "argments error!\n");
            return  (-ERROR_TSHELL_EPARAM);
        }
        
        ipaddr.addr = ipaddr_addr(ppcArgV[2]);
        if (ipaddr.addr == IPADDR_NONE) {
            fprintf(stderr, "bad inet address : %s\n", ppcArgV[2]);
            return  (-ERROR_TSHELL_EPARAM);
        }
        
        if (sscanf(ppcArgV[3], "%02x:%02x:%02x:%02x:%02x:%02x",
                   &iTemp[0], &iTemp[1], &iTemp[2], 
                   &iTemp[3], &iTemp[4], &iTemp[5]) != 6) {
            fprintf(stderr, "bad physical address : %s\n", ppcArgV[3]);
            return  (-ERROR_TSHELL_EPARAM);
        }
        
        for (i = 0; i < 6; i++) {
            ethaddr.addr[i] = (u8_t)iTemp[i];
        }
        
        LOCK_TCPIP_CORE();
        err = etharp_add_static_entry(&ipaddr, &ethaddr);
        UNLOCK_TCPIP_CORE();
        
        return  (err ? PX_ERROR : ERROR_NONE);
    
    } else if (lib_strcmp(ppcArgV[1], "-d") == 0) {                     /*  删除一个静态转换关系        */
        ip_addr_t       ipaddr;
        err_t           err;
        
        if (iArgC != 3) {                                               /*  删除全部转换关系            */
            struct netif *netif;
            
            LWIP_NETIF_LOCK();
            for (netif = netif_list; netif != LW_NULL; netif = netif->next) {
                if (netif->flags & NETIF_FLAG_ETHARP) {
                    netifapi_netif_common(netif, etharp_cleanup_netif, LW_NULL);
                }
            }
            LWIP_NETIF_UNLOCK();
            
            return  (ERROR_NONE);
        }
        
        ipaddr.addr = ipaddr_addr(ppcArgV[2]);
        if (ipaddr.addr == IPADDR_NONE) {
            fprintf(stderr, "bad inet address : %s\n", ppcArgV[2]);
            return  (-ERROR_TSHELL_EPARAM);
        }
        
        LOCK_TCPIP_CORE();
        err = etharp_remove_static_entry(&ipaddr);
        UNLOCK_TCPIP_CORE();
        
        return  (err ? PX_ERROR : ERROR_NONE);
    
    } else {
        fprintf(stderr, "argments error!\n");
        return  (-ERROR_TSHELL_EPARAM);
    }
}
Example #20
0
/**
 * Wait (forever) for a message to arrive in an mbox.
 * While waiting, timeouts are processed.
 *
 * @param mbox the mbox to fetch the message from
 * @param msg the place to store the message
 */
void
sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
{
    printf("sys_timeouts_mbox_fetch()\n");
  u32_t time_needed;
  struct sys_timeo *tmptimeout;
  sys_timeout_handler handler;
  void *arg;

 again:
  if (!next_timeout) {
      printf("No Timeout, sys_arch_mbox_fetch(mbox, msg, 0)\n");
    time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
  } else {
    if (next_timeout->time > 0) {
        //printf("Have timeout, fetching with timeout of %i\n", next_timeout->time);
      time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time);
    } else {
        //printf("No time! timing out!\n");
      time_needed = SYS_ARCH_TIMEOUT;
    }
    //printf("time_needed: %i (timeout=%i)\n", time_needed, SYS_ARCH_TIMEOUT);
    if (time_needed == SYS_ARCH_TIMEOUT) {
      /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
         could be fetched. We should now call the timeout handler and
         deallocate the memory allocated for the timeout. */
      tmptimeout = next_timeout;
      next_timeout = tmptimeout->next;
      handler = tmptimeout->h;
      arg = tmptimeout->arg;
#if LWIP_DEBUG_TIMERNAMES
      if (handler != NULL) {
        LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n",
          tmptimeout->handler_name, arg));
      }
#endif /* LWIP_DEBUG_TIMERNAMES */
      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
      if (handler != NULL) {
        /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the
           timeout handler function. */
        LOCK_TCPIP_CORE();
        handler(arg);
        UNLOCK_TCPIP_CORE();
      }
      LWIP_TCPIP_THREAD_ALIVE();

      /* We try again to fetch a message from the mbox. */
      //printf("Starting over, we didnt get a message\n");
      goto again;
    } else {
        
      /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
         occured. The time variable is set to the number of
         milliseconds we waited for the message. */
      if (time_needed < next_timeout->time) {
        next_timeout->time -= time_needed;
      } else {
        next_timeout->time = 0;
      }
    }
  }
}
Example #21
0
/**
 * The main lwIP thread. This thread has exclusive access to lwIP core functions
 * (unless access to them is not locked). Other threads communicate with this
 * thread using message boxes.
 *
 * It also starts all the timers to make sure they are running in the right
 * thread context.
 *
 * @param arg unused argument
 */
static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);

  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }

  LOCK_TCPIP_CORE();
  while (1) {                          /* MAIN Loop */
    UNLOCK_TCPIP_CORE();
    LWIP_TCPIP_THREAD_ALIVE();
    /* wait for a message, timeouts are processed while waiting */
    sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
    LOCK_TCPIP_CORE();
    switch (msg->type) {
#if LWIP_NETCONN
    case TCPIP_MSG_API:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
      msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
      break;
#endif /* LWIP_NETCONN */

#if !LWIP_TCPIP_CORE_LOCKING_INPUT
    case TCPIP_MSG_INPKT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
#if LWIP_ETHERNET
      if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
        ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
      } else
#endif /* LWIP_ETHERNET */
      {
        ip_input(msg->msg.inp.p, msg->msg.inp.netif);
      }
      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
      break;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */

#if LWIP_NETIF_API
    case TCPIP_MSG_NETIFAPI:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
      msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
      break;
#endif /* LWIP_NETIF_API */

    case TCPIP_MSG_CALLBACK:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
      msg->msg.cb.function(msg->msg.cb.ctx);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

#if LWIP_TCPIP_TIMEOUT
    case TCPIP_MSG_TIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
    case TCPIP_MSG_UNTIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
#endif /* LWIP_TCPIP_TIMEOUT */

    default:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      break;
    }
  }
}
Example #22
0
/*********************************************************************************************************
** 函数名称: __inetPing6Prepare
** 功能描述: 构造 ping 包
** 输 入  : icmp6hdrEcho  数据
**           pip6addrDest  目标 IP
**           iDataSize     数据大小
**           pcNetif       网络接口名 (NULL 表示自动确定接口)
**           pusSeqRecv    需要判断的 seq
** 输 出  : ERROR
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static INT  __inetPing6Prepare (struct icmp6_echo_hdr   *icmp6hdrEcho, 
                                struct ip6_addr         *pip6addrDest,
                                INT                      iDataSize, 
                                CPCHAR                   pcNetif,
                                UINT16                  *pusSeqRecv)
{
    static u16_t    usSeqNum = 1;
    REGISTER INT    i;
    
#if CHECKSUM_GEN_ICMP6
           INT      iError;
    struct ip6_addr ip6addrSrc;
    struct pbuf     pbuf;
    struct netif   *netif;
#endif                                                                  /*  CHECKSUM_GEN_ICMP6          */
    
    SYS_ARCH_DECL_PROTECT(x);

    icmp6hdrEcho->type = ICMP6_TYPE_EREQ;
    icmp6hdrEcho->code = 0;
    
    *pusSeqRecv = usSeqNum;
    
    icmp6hdrEcho->chksum = 0;
    icmp6hdrEcho->id     = 0xAFAF;                                      /*  ID                          */
    icmp6hdrEcho->seqno  = htons(usSeqNum);
    
    /*
     *  填充数据
     */
    for(i = 0; i < iDataSize; i++) {
        ((PCHAR)icmp6hdrEcho)[sizeof(struct icmp6_echo_hdr) + i] = (CHAR)(i % 256);
    }
    
#if CHECKSUM_GEN_ICMP6
    LOCK_TCPIP_CORE();
    if (pcNetif) {
        netif = netif_find((PCHAR)pcNetif);
        if (netif == LW_NULL) {
            UNLOCK_TCPIP_CORE();
            fprintf(stderr, "Invalid interface.\n");
            return  (PX_ERROR);
        }
    } else {
        netif = LW_NULL;
    }
    iError = __inetPing6FindSrc(netif, pip6addrDest, &ip6addrSrc);
    UNLOCK_TCPIP_CORE();
    
    if (iError == -1) {
        fprintf(stderr, "You must determine net interface.\n");
        return  (PX_ERROR);
    
    } else if (iError == -2) {
        fprintf(stderr, "Unreachable destination.\n");
        return  (PX_ERROR);
    }
    
    pbuf.next    = LW_NULL;
    pbuf.payload = (void *)icmp6hdrEcho;
    pbuf.tot_len = (u16_t)(iDataSize + sizeof(struct icmp6_echo_hdr));
    pbuf.len     = pbuf.tot_len;
    pbuf.type    = PBUF_ROM;
    pbuf.flags   = 0;
    pbuf.ref     = 1;
    
    icmp6hdrEcho->chksum = ip6_chksum_pseudo(&pbuf, IP6_NEXTH_ICMP6, pbuf.tot_len,
                                             &ip6addrSrc, pip6addrDest);
#endif                                                                  /*  CHECKSUM_GEN_ICMP6          */
    
    SYS_ARCH_PROTECT(x);
    usSeqNum++;
    SYS_ARCH_UNPROTECT(x);
    
    return  (ERROR_NONE);
}