Ejemplo n.º 1
0
static inline void psock_lost_connection(FAR struct socket *psock,
        FAR struct tcp_conn_s *conn)
{
    FAR sq_entry_t *entry;
    FAR sq_entry_t *next;

    /* Do not allow any further callbacks */

    psock->s_sndcb->flags = 0;
    psock->s_sndcb->event = NULL;

    /* Free all queued write buffers */

    for (entry = sq_peek(&conn->unacked_q); entry; entry = next)
    {
        next = sq_next(entry);
        tcp_wrbuffer_release((FAR struct tcp_wrbuffer_s *)entry);
    }

    for (entry = sq_peek(&conn->write_q); entry; entry = next)
    {
        next = sq_next(entry);
        tcp_wrbuffer_release((FAR struct tcp_wrbuffer_s *)entry);
    }

    /* Reset write buffering variables */

    sq_init(&conn->unacked_q);
    sq_init(&conn->write_q);
    conn->sent = 0;
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------------
void SN_API getTable(HSQUIRRELVM vm, Variant & out_v, SQInteger index)
{
	out_v.setDictionary();
	Variant::Dictionary & d = out_v.getDictionary();

	sq_push(vm, index);
	sq_pushnull(vm);

	while (SQ_SUCCEEDED(sq_next(vm, -2)))
	{
		if (sq_gettype(vm, -2) == OT_STRING)
		{
			const SQChar * key = nullptr;
			sq_getstring(vm, -2, &key);
			Variant & val = d[key];
			getVariant(vm, val, -1);
		}
		else
		{
			SN_WARNING("non-string keys in tables are not supported by getVariant");
		}

		sq_pop(vm, 2);
	}

	sq_pop(vm, 2); // Pop iterator and table
}
Ejemplo n.º 3
0
	template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
	{
		SQObject obj;
		sq_getstackobj(vm, index, &obj);
		sq_pushobject(vm, obj);
		sq_pushnull(vm);

		SmallVector<int32, 2> data;

		while (SQ_SUCCEEDED(sq_next(vm, -2))) {
			SQInteger tmp;
			if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
				*data.Append() = (int32)tmp;
			} else {
				sq_pop(vm, 4);
				throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
			}

			sq_pop(vm, 2);
		}
		sq_pop(vm, 2);

		Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
		arr->size = data.Length();
		memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());

		*ptr->Append() = arr;
		return arr;
	}
Ejemplo n.º 4
0
static void psock_insert_segment(FAR struct tcp_wrbuffer_s *wrb,
                                 FAR sq_queue_t *q)
{
    sq_entry_t *entry = (sq_entry_t*)wrb;
    sq_entry_t *insert = NULL;

    sq_entry_t *itr;
    for (itr = sq_peek(q); itr; itr = sq_next(itr))
    {
        FAR struct tcp_wrbuffer_s *wrb0 = (FAR struct tcp_wrbuffer_s*)itr;
        if (WRB_SEQNO(wrb0) < WRB_SEQNO(wrb))
        {
            insert = itr;
        }
        else
        {
            break;
        }
    }

    if (insert)
    {
        sq_addafter(insert, entry, q);
    }
    else
    {
        sq_addfirst(entry, q);
    }
}
Ejemplo n.º 5
0
//------------------------------------------------------------------------------
void SN_API getArray(HSQUIRRELVM vm, Variant & out_v, SQInteger index)
{
	out_v.setArray();
	Variant::Array & a = out_v.getArray();

	SQInteger len = sq_getsize(vm, index);
	SN_ASSERT(len >= 0, "Invalid array size");
	
	if (len > 0)
	{
		a.resize(len);
		s32 i = 0;

		sq_push(vm, index);
		sq_pushnull(vm);

		while (SQ_SUCCEEDED(sq_next(vm, -2)))
		{
			// -1 is the value and -2 is the key

			sq_getinteger(vm, -2, &i);
			Variant & val = a[i];
			getVariant(vm, val, -1);

			sq_pop(vm, 2); //pops key and val before the next iteration
		}

		sq_pop(vm, 2); // Pop the null iterator and array
	}
}
Ejemplo n.º 6
0
perf_counter_t
perf_alloc_once(enum perf_counter_type type, const char *name)
{
	pthread_mutex_lock(&perf_counters_mutex);
	perf_counter_t handle = (perf_counter_t)sq_peek(&perf_counters);

	while (handle != NULL) {
		if (!strcmp(handle->name, name)) {
			if (type == handle->type) {
				/* they are the same counter */
				pthread_mutex_unlock(&perf_counters_mutex);
				return handle;

			} else {
				/* same name but different type, assuming this is an error and not intended */
				pthread_mutex_unlock(&perf_counters_mutex);
				return NULL;
			}
		}

		handle = (perf_counter_t)sq_next(&handle->link);
	}

	pthread_mutex_unlock(&perf_counters_mutex);

	/* if the execution reaches here, no existing counter of that name was found */
	return perf_alloc(type, name);
}
Ejemplo n.º 7
0
std::vector<std::string>
ConsoleImpl::get_roottable()
{
  std::vector<std::string> roottable;
  HSQUIRRELVM v = script_manager->get_vm();

  sq_pushroottable(v);

  //push your table/array here
  sq_pushnull(v);  //null iterator
  while(SQ_SUCCEEDED(sq_next(v,-2)))
    {
      //here -1 is the value and -2 is the key
      const SQChar *s;
      if (SQ_SUCCEEDED(sq_getstring(v,-2, &s)))
        {
          roottable.push_back((char*)s);
        }
      else
        {
          console << "Unknown key type for element" << std::endl;
        }
                              
      sq_pop(v,2); //pops key and val before the nex iteration
    }
                          
  sq_pop(v, 1);
  
  return roottable;
}
Ejemplo n.º 8
0
static void send_insert_seqment(FAR struct uip_wrbuffer_s *segment,
                                FAR sq_queue_t *q)
{
  sq_entry_t *entry = (sq_entry_t*)segment;
  sq_entry_t *insert = NULL;

  sq_entry_t *itr;
  for (itr = sq_peek(q); itr; itr = sq_next(itr))
    {
      FAR struct uip_wrbuffer_s *segment0 = (FAR struct uip_wrbuffer_s*)itr;
      if (segment0->wb_seqno < segment->wb_seqno)
        {
          insert = itr;
        }
      else
        {
          break;
        }
    }

  if (insert)
    {
      sq_addafter(insert, entry, q);
    }
  else
    {
      sq_addfirst(entry, q);
    }
}
Ejemplo n.º 9
0
static void
hrt_call_enter(struct hrt_call *entry)
{
	struct hrt_call	*call, *next;

	call = (struct hrt_call *)sq_peek(&callout_queue);

	if ((call == NULL) || (entry->deadline < call->deadline)) {
		sq_addfirst(&entry->link, &callout_queue);
		//lldbg("call enter at head, reschedule\n");
		/* we changed the next deadline, reschedule the timer event */
		hrt_call_reschedule();

	} else {
		do {
			next = (struct hrt_call *)sq_next(&call->link);

			if ((next == NULL) || (entry->deadline < next->deadline)) {
				//lldbg("call enter after head\n");
				sq_addafter(&call->link, &entry->link, &callout_queue);
				break;
			}
		} while ((call = next) != NULL);
	}

	//lldbg("scheduled\n");
}
Ejemplo n.º 10
0
int uip_backlogdelete(FAR struct uip_conn *conn, FAR struct uip_conn *blconn)
{
  FAR struct uip_backlog_s     *bls;
  FAR struct uip_blcontainer_s *blc;
  FAR struct uip_blcontainer_s *prev;

  nllvdbg("conn=%p blconn=%p\n", conn, blconn);

#ifdef CONFIG_DEBUG
  if (!conn)
    {
      return -EINVAL;
    }
#endif

  bls = conn->backlog;
  if (bls)
    {
       /* Find the container hold the connection */

       for (blc = (FAR struct uip_blcontainer_s *)sq_peek(&bls->bl_pending), prev = NULL;
            blc;
            prev = blc, blc = (FAR struct uip_blcontainer_s *)sq_next(&blc->bc_node))
         {
            if (blc->bc_conn == blconn)
              {
                if (prev)
                  {
                    /* Remove the a container from the middle of the list of
                     * pending connections
                      */

                    (void)sq_remafter(&prev->bc_node, &bls->bl_pending);
                  }
                else
                  {
                    /* Remove the a container from the head of the list of
                     * pending connections
                     */

                    (void)sq_remfirst(&bls->bl_pending);
                  }

                /* Put container in the free list */

                blc->bc_conn = NULL;
                sq_addlast(&blc->bc_node, &bls->bl_free);
                return OK;
              }
          }

        nlldbg("Failed to find pending connection\n");
        return -EINVAL;
    }
  return OK;
}
Ejemplo n.º 11
0
void
perf_print_all(int fd)
{
	perf_counter_t handle = (perf_counter_t)sq_peek(&perf_counters);

	while (handle != NULL) {
		perf_print_counter_fd(fd, handle);
		handle = (perf_counter_t)sq_next(&handle->link);
	}
}
Ejemplo n.º 12
0
BOOL SquirrelObject::Next(SquirrelObject &key,SquirrelObject &val)
{
	if(SQ_SUCCEEDED(sq_next(m_Vm.GetVMPtr(),-2))) {
		key.AttachToStackObject(-2);
		val.AttachToStackObject(-1);
		sq_pop(m_Vm.GetVMPtr(),2);
		return TRUE;
	}
	return FALSE;
}
Ejemplo n.º 13
0
SQInteger Sq_Interpolate(HSQUIRRELVM v) {
  const SQChar *Str, *WordString;
  char Out[4096];
  sq_getstring(v, 2, &Str);
  sq_getstring(v, 3, &WordString);
  char *Poke = Out;
  const char *Peek = Str;

  char WordBuff[strlen(Str)+1];
  const char *Word[32];
  const char *WordEol[32];
  XChatTokenize(WordString, WordBuff, Word, WordEol, 32, TOKENIZE_MULTI_WORD);

  while(*Peek) {
    int Span = strcspn(Peek, "%&");
    memcpy(Poke, Peek, Span);
    Poke += Span;
    Peek += Span;
    if(*Peek == '%' || *Peek == '&') {
      char Extra = Peek[1];
      if(Extra == '%')
        *(Poke++) = '%';
      else if(Extra == '&')
        *(Poke++) = '&';
      else {
        if(isdigit(Extra)) {
          int WhichWord = Extra - '1';
          strcpy(Poke, (*Peek=='%')?Word[WhichWord]:WordEol[WhichWord]);
          Poke = strrchr(Poke, 0);
        } else { // look in the list of extra words
          int top = sq_gettop(v);;
          sq_pushnull(v); //null iterator
          while(SQ_SUCCEEDED(sq_next(v,-2))) {
             const SQChar *ThisWord;
             sq_getstring(v, -1, &ThisWord);
             if(ThisWord[0]==Extra) {
               strcpy(Poke, ThisWord+1);
               Poke = strrchr(Poke, 0);
               break;
             }
             sq_pop(v,2);
          }
          sq_pop(v,1); //pops the null iterator
          sq_settop(v, top);
        }
      }
      Peek+= 2;
    }
  }
  *Poke = 0;

  sq_pushstring(v, Out, -1);  
  return 1;
}
Ejemplo n.º 14
0
void
perf_print_all(int fd)
{
	pthread_mutex_lock(&perf_counters_mutex);
	perf_counter_t handle = (perf_counter_t)sq_peek(&perf_counters);

	while (handle != NULL) {
		perf_print_counter_fd(fd, handle);
		handle = (perf_counter_t)sq_next(&handle->link);
	}

	pthread_mutex_unlock(&perf_counters_mutex);
}
Ejemplo n.º 15
0
void
perf_iterate_all(perf_callback cb, void *user)
{
	pthread_mutex_lock(&perf_counters_mutex);
	perf_counter_t handle = (perf_counter_t)sq_peek(&perf_counters);

	while (handle != NULL) {
		cb(handle, user);
		handle = (perf_counter_t)sq_next(&handle->link);
	}

	pthread_mutex_unlock(&perf_counters_mutex);
}
Ejemplo n.º 16
0
void
perf_reset_all(void)
{
	perf_counter_t handle = (perf_counter_t)sq_peek(&perf_counters);

	while (handle != NULL) {
		perf_reset(handle);
		handle = (perf_counter_t)sq_next(&handle->link);
	}
	for (int i = 0; i <= latency_bucket_count; i++) {
		latency_counters[i] = 0;
	}
}
Ejemplo n.º 17
0
static void handle_queued_events(struct conman_client_s *client,
                                 sq_queue_t *qevents)
{
  struct queued_event_s *item;

  item = (void *)sq_peek(qevents);
  while (item)
    {
      struct queued_event_s *curr = item;

      item = (void *)sq_next(&item->node);

      client->event_callback(client, curr->type, curr->payload,
                             curr->payloadlen, client->event_priv);
      free(curr->payload);
      free(curr);
    }
}
Ejemplo n.º 18
0
SQInteger AIInfo::AddLabels(HSQUIRRELVM vm)
{
	const SQChar *sq_setting_name;
	if (SQ_FAILED(sq_getstring(vm, -2, &sq_setting_name))) return SQ_ERROR;
	const char *setting_name = SQ2OTTD(sq_setting_name);

	AIConfigItem *config = NULL;
	for (AIConfigItemList::iterator it = this->config_list.begin(); it != this->config_list.end(); it++) {
		if (strcmp((*it).name, setting_name) == 0) config = &(*it);
	}

	if (config == NULL) {
		char error[1024];
		snprintf(error, sizeof(error), "Trying to add labels for non-defined setting '%s'", setting_name);
		this->engine->ThrowError(error);
		return SQ_ERROR;
	}
	if (config->labels != NULL) return SQ_ERROR;

	config->labels = new LabelMapping;

	/* Read the table and find all labels */
	sq_pushnull(vm);
	while (SQ_SUCCEEDED(sq_next(vm, -2))) {
		const SQChar *sq_key;
		const SQChar *sq_label;
		if (SQ_FAILED(sq_getstring(vm, -2, &sq_key))) return SQ_ERROR;
		if (SQ_FAILED(sq_getstring(vm, -1, &sq_label))) return SQ_ERROR;
		/* Because squirrel doesn't support identifiers starting with a digit,
		 * we skip the first character. */
		const char *key_string = SQ2OTTD(sq_key);
		int key = atoi(key_string + 1);
		const char *label = SQ2OTTD(sq_label);

		/* !Contains() prevents strdup from leaking. */
		if (!config->labels->Contains(key)) config->labels->Insert(key, strdup(label));

		sq_pop(vm, 2);
	}
	sq_pop(vm, 1);

	return 0;
}
Ejemplo n.º 19
0
static inline void pm_changeall(enum pm_state_e newstate)
{
  FAR sq_entry_t *entry;

  /* Visit each registered callback structure. */

  for (entry = sq_peek(&g_pmglobals.registry); entry; entry = sq_next(entry))
    {
      /* Is the notification callback supported? */

      FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
      if (cb->notify)
        {
          /* Yes.. notify the driver */

          cb->notify(cb, newstate);
        }
    }
}
Ejemplo n.º 20
0
/****************************************************************************
 * Name: ubgps_publish_event
 *
 * Description:
 *   Publish event to registered callbacks
 *
 * Input Parameters:
 *   gps         - GPS object
 *   event       - Pointer to published event
 *
 * Returned Values:
 *   Status
 *
 ****************************************************************************/
void ubgps_publish_event(struct ubgps_s * const gps, struct gps_event_s const * const event)
{
  struct gps_callback_entry_s const * cb;

  DEBUGASSERT(gps && event);

  /* Check if any callback is interested of this event */

  if (!(gps->callback_event_mask & event->id))
    return;

  cb = (struct gps_callback_entry_s *)sq_peek(&gps->callbacks);
  while (cb)
    {
      if ((cb->event_mask & event->id) && cb->callback)
        cb->callback(event, cb->priv);

      cb = (struct gps_callback_entry_s *)sq_next(&cb->entry);
    }
}
Ejemplo n.º 21
0
void __conman_send_boardcast_event(struct conman_s *conman,
                                   enum conman_msgs_ids type,
                                   const void *payload,
                                   size_t payloadlen)
{
  struct conman_sd_entry_s *client;
  struct conman_resp_hdr hdr = {};
  int send_count = 0;
  int ret;

  hdr.head.id = type;
  hdr.head.len = payloadlen;
  hdr.respval = CONMAN_RESP_EVENT;

  for (client = (struct conman_sd_entry_s *)sq_peek(&conman->server.sds);
       client != NULL;
       client = (struct conman_sd_entry_s *)sq_next(&client->entry))
    {
      if (!client->events_enabled)
        {
          continue;
        }

      ret = __conman_util_block_write(client->sd, &hdr, sizeof(hdr));
      if (ret < 0)
        {
          continue;
        }

      ret = __conman_util_block_write(client->sd, payload, hdr.head.len);
      if (ret < 0)
        {
          continue;
        }

      send_count++;
    }

  conman_dbg("send boardcast event (type=%d) to %d clients.\n",
             type, send_count);
}
Ejemplo n.º 22
0
void __ubgps_gc_callbacks(struct ubgps_s * const gps)
{
  struct gps_callback_entry_s * cb, * cbnext;

  /* Search for callback in queue */

  cb = (struct gps_callback_entry_s *)sq_peek(&gps->callbacks);
  while (cb)
    {
      /* Save next callback entry */

      cbnext = (struct gps_callback_entry_s *)sq_next(&cb->entry);

      if (cb->event_mask == 0)
        {
          /* Free unactive callback. */

          sq_rem(&cb->entry, &gps->callbacks);
          free(cb);
        }

      cb = cbnext;
    }
}
Ejemplo n.º 23
0
static int pm_prepall(enum pm_state_e newstate)
{
  FAR sq_entry_t *entry;
  int ret = OK;

  /* Visit each registered callback structure. */

  for (entry = sq_peek(&g_pmglobals.registry);
       entry && ret == OK;
       entry = sq_next(entry))
    {
      /* Is the prepare callback supported? */

      FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
      if (cb->prepare)
        {
          /* Yes.. prepare the driver */

          ret = cb->prepare(cb, newstate);
        }
    }

  return ret;
}
Ejemplo n.º 24
0
std::vector<std::string> get_table_keys(HSQUIRRELVM vm)
{
  std::vector<std::string> keys;

  sq_pushnull(vm);
  while(SQ_SUCCEEDED(sq_next(vm, -2)))
  {
    //here -1 is the value and -2 is the key
    const char* result;
    if(SQ_FAILED(sq_getstring(vm, -2, &result)))
    {
      throw scripting::SquirrelError(vm, "Couldn't get string value for key");
    }
    else
    {
      keys.push_back(result);
    }

    // pops key and val before the next iteration
    sq_pop(vm, 2);
  }

  return keys;
}
Ejemplo n.º 25
0
/* static */ bool ScriptInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)
{
	if (max_depth == 0) {
		ScriptLog::Error("Savedata can only be nested to 25 deep. No data saved."); // SQUIRREL_MAX_DEPTH = 25
		return false;
	}

	switch (sq_gettype(vm, index)) {
		case OT_INTEGER: {
			if (!test) {
				_script_sl_byte = SQSL_INT;
				SlObject(NULL, _script_byte);
			}
			SQInteger res;
			sq_getinteger(vm, index, &res);
			if (!test) {
				int value = (int)res;
				SlArray(&value, 1, SLE_INT32);
			}
			return true;
		}

		case OT_STRING: {
			if (!test) {
				_script_sl_byte = SQSL_STRING;
				SlObject(NULL, _script_byte);
			}
			const SQChar *res;
			sq_getstring(vm, index, &res);
			/* @bug if a string longer than 512 characters is given to SQ2OTTD, the
			 *  internal buffer overflows. */
			const char *buf = SQ2OTTD(res);
			size_t len = strlen(buf) + 1;
			if (len >= 255) {
				ScriptLog::Error("Maximum string length is 254 chars. No data saved.");
				return false;
			}
			if (!test) {
				_script_sl_byte = (byte)len;
				SlObject(NULL, _script_byte);
				SlArray(const_cast<char *>(buf), len, SLE_CHAR);
			}
			return true;
		}

		case OT_ARRAY: {
			if (!test) {
				_script_sl_byte = SQSL_ARRAY;
				SlObject(NULL, _script_byte);
			}
			sq_pushnull(vm);
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
				/* Store the value */
				bool res = SaveObject(vm, -1, max_depth - 1, test);
				sq_pop(vm, 2);
				if (!res) {
					sq_pop(vm, 1);
					return false;
				}
			}
			sq_pop(vm, 1);
			if (!test) {
				_script_sl_byte = SQSL_ARRAY_TABLE_END;
				SlObject(NULL, _script_byte);
			}
			return true;
		}

		case OT_TABLE: {
			if (!test) {
				_script_sl_byte = SQSL_TABLE;
				SlObject(NULL, _script_byte);
			}
			sq_pushnull(vm);
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
				/* Store the key + value */
				bool res = SaveObject(vm, -2, max_depth - 1, test) && SaveObject(vm, -1, max_depth - 1, test);
				sq_pop(vm, 2);
				if (!res) {
					sq_pop(vm, 1);
					return false;
				}
			}
			sq_pop(vm, 1);
			if (!test) {
				_script_sl_byte = SQSL_ARRAY_TABLE_END;
				SlObject(NULL, _script_byte);
			}
			return true;
		}

		case OT_BOOL: {
			if (!test) {
				_script_sl_byte = SQSL_BOOL;
				SlObject(NULL, _script_byte);
			}
			SQBool res;
			sq_getbool(vm, index, &res);
			if (!test) {
				_script_sl_byte = res ? 1 : 0;
				SlObject(NULL, _script_byte);
			}
			return true;
		}

		case OT_NULL: {
			if (!test) {
				_script_sl_byte = SQSL_NULL;
				SlObject(NULL, _script_byte);
			}
			return true;
		}

		default:
			ScriptLog::Error("You tried to save an unsupported type. No data saved.");
			return false;
	}
}
Ejemplo n.º 26
0
/* static */ bool ScriptAdmin::MakeJSON(HSQUIRRELVM vm, SQInteger index, int max_depth, std::string &data)
{
	if (max_depth == 0) {
		ScriptLog::Error("Send parameters can only be nested to 25 deep. No data sent."); // SQUIRREL_MAX_DEPTH = 25
		return false;
	}

	switch (sq_gettype(vm, index)) {
		case OT_INTEGER: {
			SQInteger res;
			sq_getinteger(vm, index, &res);

			char buf[10];
			snprintf(buf, sizeof(buf), "%d", (int32)res);
			data = buf;
			return true;
		}

		case OT_STRING: {
			const SQChar *res;
			sq_getstring(vm, index, &res);

			/* @bug if a string longer than 512 characters is given to SQ2OTTD, the
			 *  internal buffer overflows. */
			const char *buf = SQ2OTTD(res);
			size_t len = strlen(buf) + 1;
			if (len >= 255) {
				ScriptLog::Error("Maximum string length is 254 chars. No data sent.");
				return false;
			}

			data = std::string("\"") + buf + "\"";
			return true;
		}

		case OT_ARRAY: {
			data = "[ ";

			bool first = true;
			sq_pushnull(vm);
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
				if (!first) data += ", ";
				if (first) first = false;

				std::string tmp;

				bool res = MakeJSON(vm, -1, max_depth - 1, tmp);
				sq_pop(vm, 2);
				if (!res) {
					sq_pop(vm, 1);
					return false;
				}
				data += tmp;
			}
			sq_pop(vm, 1);
			data += " ]";
			return true;
		}

		case OT_TABLE: {
			data = "{ ";

			bool first = true;
			sq_pushnull(vm);
			while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
				if (!first) data += ", ";
				if (first) first = false;

				std::string key;
				std::string value;

				/* Store the key + value */
				bool res = MakeJSON(vm, -2, max_depth - 1, key) && MakeJSON(vm, -1, max_depth - 1, value);
				sq_pop(vm, 2);
				if (!res) {
					sq_pop(vm, 1);
					return false;
				}
				data += key + ": " + value;
			}
			sq_pop(vm, 1);
			data += " }";
			return true;
		}

		case OT_BOOL: {
			SQBool res;
			sq_getbool(vm, index, &res);

			if (res) {
				data = "true";
				return true;
			}

			data = "false";
			return true;
		}

		case OT_NULL: {
			data = "null";
			return true;
		}

		default:
			ScriptLog::Error("You tried to send an unsupported type. No data sent.");
			return false;
	}
}
Ejemplo n.º 27
0
/*
** Copies values from State src to State dst.
*/
static SQRESULT copy_values_between_vms (HSQUIRRELVM dst, HSQUIRRELVM src, int argc, int argIdx)
{
    SQRESULT _rc_;
    sq_reservestack(dst, argc + 20);
    argc += argIdx; //we will work with argc args starting at argIdx
    for (; argIdx < argc; argIdx++)
    {
        switch (sq_gettype(src, argIdx))
        {
        case OT_INTEGER:
            SQ_GET_INTEGER(src, argIdx, vint);
            sq_pushinteger(dst, vint);
            break;

        case OT_FLOAT:
            SQ_GET_FLOAT(src, argIdx, vfloat);
            sq_pushfloat (dst, vfloat);
            break;

        case OT_BOOL:
            SQ_GET_BOOL(src, argIdx, vbool);
            sq_pushbool (dst, vbool);
            break;

        case OT_STRING:
        {
            SQ_GET_STRING(src, argIdx, vstr)
            sq_pushstring (dst, vstr, vstr_size);
        }
        break;

        case OT_ARRAY:
        {
            SQInteger size = sq_getsize(src, argIdx);
            sq_newarray(dst, size);
            for(SQInteger i=0; i<size; ++i)
            {
                sq_pushinteger(src, i);
                sq_get(src, -2);
                sq_pushinteger(dst, i);
                if(copy_values_between_vms(dst, src, 1, sq_gettop(src)) != SQ_OK) return SQ_ERROR;
                sq_poptop(src);
                sq_set(dst, -3);
            }
        }
        break;

        case OT_TABLE:
        {
            sq_newtable(dst);
            sq_pushnull(src);
            while(sq_next(src, -2) == SQ_OK)
            {
                SQInteger src_top = sq_gettop(src);
                if(copy_values_between_vms(dst, src, 1, src_top-1) != SQ_OK
                        || copy_values_between_vms(dst, src, 1, src_top) != SQ_OK) return SQ_ERROR;
                sq_newslot(dst, -3, SQFalse);
                sq_pop(src, 2);
            }
            sq_pop(src,1);
        }
        break;

        case OT_USERPOINTER:
        {
            SQUserPointer ptr;
            sq_getuserpointer(src, argIdx, &ptr);
            sq_pushuserpointer(dst, ptr);
        }
        break;

        case OT_NULL:
            sq_pushnull(dst);
            break;

        default:
            return SQ_ERROR;
        }
    }
    return SQ_OK;
}
Ejemplo n.º 28
0
static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
                                     FAR void *pvconn, FAR void *pvpriv,
                                     uint16_t flags)
{
    FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn;
    FAR struct socket *psock = (FAR struct socket *)pvpriv;

    nllvdbg("flags: %04x\n", flags);

    /* If this packet contains an acknowledgement, then update the count of
     * acknowledged bytes.
     */

    if ((flags & TCP_ACKDATA) != 0)
    {
        FAR struct tcp_wrbuffer_s *wrb;
        FAR sq_entry_t *entry;
        FAR sq_entry_t *next;
        uint32_t ackno;

        ackno = tcp_getsequence(TCPBUF->ackno);
        nllvdbg("ACK: ackno=%u flags=%04x\n", ackno, flags);

        /* Look at every write buffer in the unacked_q.  The unacked_q
         * holds write buffers that have been entirely sent, but which
         * have not yet been ACKed.
         */

        for (entry = sq_peek(&conn->unacked_q); entry; entry = next)
        {
            uint32_t lastseq;

            /* Check of some or all of this write buffer has been ACKed. */

            next = sq_next(entry);
            wrb = (FAR struct tcp_wrbuffer_s*)entry;

            /* If the ACKed sequence number is greater than the start
             * sequence number of the write buffer, then some or all of
             * the write buffer has been ACKed.
             */

            if (ackno > WRB_SEQNO(wrb))
            {
                /* Get the sequence number at the end of the data */

                lastseq = WRB_SEQNO(wrb) + WRB_PKTLEN(wrb);
                nllvdbg("ACK: wrb=%p seqno=%u lastseq=%u pktlen=%u ackno=%u\n",
                        wrb, WRB_SEQNO(wrb), lastseq, WRB_PKTLEN(wrb), ackno);

                /* Has the entire buffer been ACKed? */

                if (ackno >= lastseq)
                {
                    nllvdbg("ACK: wrb=%p Freeing write buffer\n", wrb);

                    /* Yes... Remove the write buffer from ACK waiting queue */

                    sq_rem(entry, &conn->unacked_q);

                    /* And return the write buffer to the pool of free buffers */

                    tcp_wrbuffer_release(wrb);
                }
                else
                {
                    unsigned int trimlen;

                    /* No, then just trim the ACKed bytes from the beginning
                     * of the write buffer.  This will free up some I/O buffers
                     * that can be reused while are still sending the last
                     * buffers in the chain.
                     */

                    trimlen = ackno - WRB_SEQNO(wrb);
                    if (trimlen > WRB_SENT(wrb))
                    {
                        /* More data has been ACKed then we have sent? */

                        trimlen = WRB_SENT(wrb);
                    }

                    nllvdbg("ACK: wrb=%p trim %u bytes\n", wrb, trimlen);

                    WRB_TRIM(wrb, trimlen);
                    WRB_SEQNO(wrb) = ackno;
                    WRB_SENT(wrb) -= trimlen;

                    /* Set the new sequence number for what remains */

                    nllvdbg("ACK: wrb=%p seqno=%u pktlen=%u\n",
                            wrb, WRB_SEQNO(wrb), WRB_PKTLEN(wrb));
                }
            }
        }

        /* A special case is the head of the write_q which may be partially
         * sent and so can still have un-ACKed bytes that could get ACKed
         * before the entire write buffer has even been sent.
         */

        wrb = (FAR struct tcp_wrbuffer_s*)sq_peek(&conn->write_q);
        if (wrb && WRB_SENT(wrb) > 0 && ackno > WRB_SEQNO(wrb))
        {
            uint32_t nacked;

            /* Number of bytes that were ACKed */

            nacked = ackno - WRB_SEQNO(wrb);
            if (nacked > WRB_SENT(wrb))
            {
                /* More data has been ACKed then we have sent? ASSERT? */

                nacked = WRB_SENT(wrb);
            }

            nllvdbg("ACK: wrb=%p seqno=%u nacked=%u sent=%u ackno=%u\n",
                    wrb, WRB_SEQNO(wrb), nacked, WRB_SENT(wrb), ackno);

            /* Trim the ACKed bytes from the beginning of the write buffer. */

            WRB_TRIM(wrb, nacked);
            WRB_SEQNO(wrb) = ackno;
            WRB_SENT(wrb) -= nacked;

            nllvdbg("ACK: wrb=%p seqno=%u pktlen=%u sent=%u\n",
                    wrb, WRB_SEQNO(wrb), WRB_PKTLEN(wrb), WRB_SENT(wrb));
        }
    }

    /* Check for a loss of connection */

    else if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
    {
        nllvdbg("Lost connection: %04x\n", flags);

        /* Report not connected */

        net_lostconnection(psock, flags);

        /* Free write buffers and terminate polling */

        psock_lost_connection(psock, conn);
        return flags;
    }

    /* Check if we are being asked to retransmit data */

    else if ((flags & TCP_REXMIT) != 0)
    {
        FAR struct tcp_wrbuffer_s *wrb;
        FAR sq_entry_t *entry;

        nllvdbg("REXMIT: %04x\n", flags);

        /* If there is a partially sent write buffer at the head of the
         * write_q?  Has anything been sent from that write buffer?
         */

        wrb = (FAR struct tcp_wrbuffer_s *)sq_peek(&conn->write_q);
        nllvdbg("REXMIT: wrb=%p sent=%u\n", wrb, wrb ? WRB_SENT(wrb) : 0);

        if (wrb != NULL && WRB_SENT(wrb) > 0)
        {
            FAR struct tcp_wrbuffer_s *tmp;
            uint16_t sent;

            /* Yes.. Reset the number of bytes sent sent from the write buffer */

            sent = WRB_SENT(wrb);
            if (conn->unacked > sent)
            {
                conn->unacked -= sent;
            }
            else
            {
                conn->unacked = 0;
            }

            if (conn->sent > sent)
            {
                conn->sent -= sent;
            }
            else
            {
                conn->sent = 0;
            }

            WRB_SENT(wrb) = 0;
            nllvdbg("REXMIT: wrb=%p sent=%u, conn unacked=%d sent=%d\n",
                    wrb, WRB_SENT(wrb), conn->unacked, conn->sent);

            /* Increment the retransmit count on this write buffer. */

            if (++WRB_NRTX(wrb) >= TCP_MAXRTX)
            {
                nlldbg("Expiring wrb=%p nrtx=%u\n", wrb, WRB_NRTX(wrb));

                /* The maximum retry count as been exhausted. Remove the write
                 * buffer at the head of the queue.
                 */

                tmp = (FAR struct tcp_wrbuffer_s *)sq_remfirst(&conn->write_q);
                DEBUGASSERT(tmp == wrb);
                UNUSED(tmp);

                /* And return the write buffer to the free list */

                tcp_wrbuffer_release(wrb);

                /* NOTE expired is different from un-ACKed, it is designed to
                 * represent the number of segments that have been sent,
                 * retransmitted, and un-ACKed, if expired is not zero, the
                 * connection will be closed.
                 *
                 * field expired can only be updated at TCP_ESTABLISHED state
                 */

                conn->expired++;
            }
        }

        /* Move all segments that have been sent but not ACKed to the write
         * queue again note, the un-ACKed segments are put at the head of the
         * write_q so they can be resent as soon as possible.
         */

        while ((entry = sq_remlast(&conn->unacked_q)) != NULL)
        {
            wrb = (FAR struct tcp_wrbuffer_s*)entry;
            uint16_t sent;

            /* Reset the number of bytes sent sent from the write buffer */

            sent = WRB_SENT(wrb);
            if (conn->unacked > sent)
            {
                conn->unacked -= sent;
            }
            else
            {
                conn->unacked = 0;
            }

            if (conn->sent > sent)
            {
                conn->sent -= sent;
            }
            else
            {
                conn->sent = 0;
            }

            WRB_SENT(wrb) = 0;
            nllvdbg("REXMIT: wrb=%p sent=%u, conn unacked=%d sent=%d\n",
                    wrb, WRB_SENT(wrb), conn->unacked, conn->sent);

            /* Free any write buffers that have exceed the retry count */

            if (++WRB_NRTX(wrb) >= TCP_MAXRTX)
            {
                nlldbg("Expiring wrb=%p nrtx=%u\n", wrb, WRB_NRTX(wrb));

                /* Return the write buffer to the free list */

                tcp_wrbuffer_release(wrb);

                /* NOTE expired is different from un-ACKed, it is designed to
                 * represent the number of segments that have been sent,
                 * retransmitted, and un-ACKed, if expired is not zero, the
                 * connection will be closed.
                 *
                 * field expired can only be updated at TCP_ESTABLISHED state
                 */

                conn->expired++;
                continue;
            }
            else
            {
                /* Insert the write buffer into the write_q (in sequence
                 * number order).  The retransmission will occur below
                 * when the write buffer with the lowest sequenc number
                 * is pulled from the write_q again.
                 */

                nllvdbg("REXMIT: Moving wrb=%p nrtx=%u\n", wrb, WRB_NRTX(wrb));

                psock_insert_segment(wrb, &conn->write_q);
            }
        }
    }

    /* Check if the outgoing packet is available (it may have been claimed
     * by a sendto interrupt serving a different thread).
     */

    if (dev->d_sndlen > 0)
    {
        /* Another thread has beat us sending data, wait for the next poll */

        return flags;
    }

    /* We get here if (1) not all of the data has been ACKed, (2) we have been
     * asked to retransmit data, (3) the connection is still healthy, and (4)
     * the outgoing packet is available for our use.  In this case, we are
     * now free to send more data to receiver -- UNLESS the buffer contains
     * unprocessed incoming data.  In that event, we will have to wait for the
     * next polling cycle.
     */

    if ((conn->tcpstateflags & TCP_ESTABLISHED) &&
            (flags & (TCP_POLL | TCP_REXMIT)) &&
            !(sq_empty(&conn->write_q)))
    {
        /* Check if the destination IP address is in the ARP table.  If not,
         * then the send won't actually make it out... it will be replaced with
         * an ARP request.
         *
         * NOTE 1: This could be an expensive check if there are a lot of
         * entries in the ARP table.
         *
         * NOTE 2: If we are actually harvesting IP addresses on incoming IP
         * packets, then this check should not be necessary; the MAC mapping
         * should already be in the ARP table in many cases.
         *
         * NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP
         * address mapping is already in the ARP table.
         */

#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \
    !defined(CONFIG_NET_ARP_SEND)
        if (arp_find(conn->ripaddr) != NULL)
#endif
        {
            FAR struct tcp_wrbuffer_s *wrb;
            size_t sndlen;

            /* Peek at the head of the write queue (but don't remove anything
             * from the write queue yet).  We know from the above test that
             * the write_q is not empty.
             */

            wrb = (FAR struct tcp_wrbuffer_s *)sq_peek(&conn->write_q);
            DEBUGASSERT(wrb);

            /* Get the amount of data that we can send in the next packet.
             * We will send either the remaining data in the buffer I/O
             * buffer chain, or as much as will fit given the MSS and current
             * window size.
             */

            sndlen = WRB_PKTLEN(wrb) - WRB_SENT(wrb);
            if (sndlen > tcp_mss(conn))
            {
                sndlen = tcp_mss(conn);
            }

            if (sndlen > conn->winsize)
            {
                sndlen = conn->winsize;
            }

            nllvdbg("SEND: wrb=%p pktlen=%u sent=%u sndlen=%u\n",
                    wrb, WRB_PKTLEN(wrb), WRB_SENT(wrb), sndlen);

            /* Set the sequence number for this segment.  If we are
             * retransmitting, then the sequence number will already
             * be set for this write buffer.
             */

            if (WRB_SEQNO(wrb) == (unsigned)-1)
            {
                WRB_SEQNO(wrb) = conn->isn + conn->sent;
            }

            /* The TCP stack updates sndseq on receipt of ACK *before*
             * this function is called. In that case sndseq will point
             * to the next unacknowledged byte (which might have already
             * been sent). We will overwrite the value of sndseq here
             * before the packet is sent.
             */

            tcp_setsequence(conn->sndseq, WRB_SEQNO(wrb) + WRB_SENT(wrb));

            /* Then set-up to send that amount of data with the offset
             * corresponding to the amount of data already sent. (this
             * won't actually happen until the polling cycle completes).
             */

            devif_iob_send(dev, WRB_IOB(wrb), sndlen, WRB_SENT(wrb));

            /* Remember how much data we send out now so that we know
             * when everything has been acknowledged.  Just increment
             * the amount of data sent. This will be needed in sequence
             * number calculations.
             */

            conn->unacked += sndlen;
            conn->sent    += sndlen;

            nllvdbg("SEND: wrb=%p nrtx=%u unacked=%u sent=%u\n",
                    wrb, WRB_NRTX(wrb), conn->unacked, conn->sent);

            /* Increment the count of bytes sent from this write buffer */

            WRB_SENT(wrb) += sndlen;

            nllvdbg("SEND: wrb=%p sent=%u pktlen=%u\n",
                    wrb, WRB_SENT(wrb), WRB_PKTLEN(wrb));

            /* Remove the write buffer from the write queue if the
             * last of the data has been sent from the buffer.
             */

            DEBUGASSERT(WRB_SENT(wrb) <= WRB_PKTLEN(wrb));
            if (WRB_SENT(wrb) >= WRB_PKTLEN(wrb))
            {
                FAR struct tcp_wrbuffer_s *tmp;

                nllvdbg("SEND: wrb=%p Move to unacked_q\n", wrb);

                tmp = (FAR struct tcp_wrbuffer_s *)sq_remfirst(&conn->write_q);
                DEBUGASSERT(tmp == wrb);
                UNUSED(tmp);

                /* Put the I/O buffer chain in the un-acked queue; the
                 * segment is waiting for ACK again
                 */

                psock_insert_segment(wrb, &conn->unacked_q);
            }

            /* Only one data can be sent by low level driver at once,
             * tell the caller stop polling the other connection.
             */

            flags &= ~TCP_POLL;
        }
    }

    /* Continue waiting */

    return flags;
}
Ejemplo n.º 29
0
SQInteger AIInfo::AddSetting(HSQUIRRELVM vm)
{
	AIConfigItem config;
	memset(&config, 0, sizeof(config));
	config.max_value = 1;
	config.step_size = 1;
	uint items = 0;

	/* Read the table, and find all properties we care about */
	sq_pushnull(vm);
	while (SQ_SUCCEEDED(sq_next(vm, -2))) {
		const SQChar *sqkey;
		if (SQ_FAILED(sq_getstring(vm, -2, &sqkey))) return SQ_ERROR;
		const char *key = SQ2OTTD(sqkey);

		if (strcmp(key, "name") == 0) {
			const SQChar *sqvalue;
			if (SQ_FAILED(sq_getstring(vm, -1, &sqvalue))) return SQ_ERROR;
			char *name = strdup(SQ2OTTD(sqvalue));
			char *s;
			/* Don't allow '=' and ',' in configure setting names, as we need those
			 *  2 chars to nicely store the settings as a string. */
			while ((s = strchr(name, '=')) != NULL) *s = '_';
			while ((s = strchr(name, ',')) != NULL) *s = '_';
			config.name = name;
			items |= 0x001;
		} else if (strcmp(key, "description") == 0) {
			const SQChar *sqdescription;
			if (SQ_FAILED(sq_getstring(vm, -1, &sqdescription))) return SQ_ERROR;
			config.description = strdup(SQ2OTTD(sqdescription));
			items |= 0x002;
		} else if (strcmp(key, "min_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.min_value = res;
			items |= 0x004;
		} else if (strcmp(key, "max_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.max_value = res;
			items |= 0x008;
		} else if (strcmp(key, "easy_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.easy_value = res;
			items |= 0x010;
		} else if (strcmp(key, "medium_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.medium_value = res;
			items |= 0x020;
		} else if (strcmp(key, "hard_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.hard_value = res;
			items |= 0x040;
		} else if (strcmp(key, "random_deviation") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.random_deviation = res;
			items |= 0x200;
		} else if (strcmp(key, "custom_value") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.custom_value = res;
			items |= 0x080;
		} else if (strcmp(key, "step_size") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.step_size = res;
		} else if (strcmp(key, "flags") == 0) {
			SQInteger res;
			if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
			config.flags = (AIConfigFlags)res;
			items |= 0x100;
		} else {
			char error[1024];
			snprintf(error, sizeof(error), "unknown setting property '%s'", key);
			this->engine->ThrowError(error);
			return SQ_ERROR;
		}

		sq_pop(vm, 2);
	}
	sq_pop(vm, 1);

	/* Don't allow both random_deviation and AICONFIG_RANDOM to
	 * be set for the same config item. */
	if ((items & 0x200) != 0 && (config.flags & AICONFIG_RANDOM) != 0) {
		char error[1024];
		snprintf(error, sizeof(error), "Setting both random_deviation and AICONFIG_RANDOM is not allowed");
		this->engine->ThrowError(error);
		return SQ_ERROR;
	}
	/* Reset the bit for random_deviation as it's optional. */
	items &= ~0x200;

	/* Make sure all properties are defined */
	uint mask = (config.flags & AICONFIG_BOOLEAN) ? 0x1F3 : 0x1FF;
	if (items != mask) {
		char error[1024];
		snprintf(error, sizeof(error), "please define all properties of a setting (min/max not allowed for booleans)");
		this->engine->ThrowError(error);
		return SQ_ERROR;
	}

	this->config_list.push_back(config);
	return 0;
}
Ejemplo n.º 30
0
bool CSquirrelArgument::pushFromStack(SQVM * pVM, int idx)
{
	reset();
	SQObjectPtr obj = stack_get(pVM, idx);

	switch(obj._type)
	{
	case OT_NULL:
		// Nothing needed
		break;
	case OT_INTEGER:
		data.i = obj._unVal.nInteger;
		break;
	case OT_BOOL:
		data.b = (obj._unVal.nInteger != 0);
		break;
	case OT_FLOAT:
		data.f = obj._unVal.fFloat;
		break;
	case OT_STRING:
		data.str = new String(obj._unVal.pString->_val);
		break;
	case OT_TABLE:
		{
			CSquirrelArguments * pArguments = new CSquirrelArguments();
			sq_push(pVM, idx);
			sq_pushnull(pVM);

			while(SQ_SUCCEEDED(sq_next(pVM, -2)))
			{
				if(!pArguments->pushFromStack(pVM, -2) || !pArguments->pushFromStack(pVM, -1))
				{
					sq_pop(pVM, 4);
					delete pArguments;
					return false;
				}

				sq_pop(pVM, 2);
			}

			sq_pop(pVM, 2);
			data.pArray = pArguments;
		}
		break;
	case OT_ARRAY:
		{
			CSquirrelArguments * pArguments = new CSquirrelArguments();
			sq_push(pVM, idx);
			sq_pushnull(pVM);

			while(SQ_SUCCEEDED(sq_next(pVM, -2)))
			{
				if(!pArguments->pushFromStack(pVM, -1))
				{
					sq_pop(pVM, 4);
					delete pArguments;
					return false;
				}

				sq_pop(pVM, 2);
			}

			sq_pop(pVM, 2);
			data.pArray = pArguments;
		}
		break;
	case OT_CLOSURE:
	case OT_NATIVECLOSURE:
		data.sqObject = SQObject(obj);
		break;
	case OT_INSTANCE:
		data.pInstance = obj._unVal.pInstance;
		break;
	default:
		return false;
		break;
	}

	type = obj._type;
	return true;
}