Exemple #1
0
void net_context_put(struct net_context *context)
{
	if (!context) {
		return;
	}

	nano_sem_take(&contexts_lock, TICKS_UNLIMITED);

	if (context->tuple.ip_proto == IPPROTO_UDP) {
		if (net_context_get_receiver_registered(context)) {
			struct simple_udp_connection *udp =
				net_context_get_udp_connection(context);
				simple_udp_unregister(udp);
		}
	}

#ifdef CONFIG_NETWORKING_WITH_TCP
	if (context->tcp_type == NET_TCP_TYPE_SERVER) {
		tcp_unlisten(UIP_HTONS(context->tuple.local_port),
			     &context->tcp);
	}
#endif

	memset(&context->tuple, 0, sizeof(context->tuple));
	memset(&context->udp, 0, sizeof(context->udp));
	context->receiver_registered = false;

	context_sem_give(&contexts_lock);
}
Exemple #2
0
void net_context_init(void)
{
	int i;

	nano_sem_init(&contexts_lock);

	memset(contexts, 0, sizeof(contexts));

	for (i = 0; i < NET_MAX_CONTEXT; i++) {
		nano_fifo_init(&contexts[i].rx_queue);
	}

	context_sem_give(&contexts_lock);
}
Exemple #3
0
void net_context_put(struct net_context *context)
{
	int i;

	nano_sem_take_wait(&contexts_lock);

	for (i = 0; i < NET_MAX_CONTEXT; i++) {
		if (contexts[i].tuple.remote_port) {
			memset(&contexts[i].tuple, 0,
						sizeof(contexts[i].tuple));
			break;
		}
	}

	context_sem_give(&contexts_lock);
}
Exemple #4
0
struct net_context *net_context_get(enum ip_protocol ip_proto,
					const struct net_addr *remote_addr,
					uint16_t remote_port,
					struct net_addr *local_addr,
					uint16_t local_port)
{
#ifdef CONFIG_NETWORKING_WITH_IPV6
	const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
	const uip_ds6_addr_t *uip_addr;
	uip_ipaddr_t ipaddr;
#endif
	int i;
	struct net_context *context = NULL;

	/* User must provide storage for the local address. */
	if (!local_addr) {
		return NULL;
	}

#ifdef CONFIG_NETWORKING_WITH_IPV6
	if (memcmp(&local_addr->in6_addr, &in6addr_any,
				  sizeof(in6addr_any)) == 0) {
		uip_addr = uip_ds6_get_global(-1);
		if (!uip_addr) {
			uip_addr = uip_ds6_get_link_local(-1);
		}
		if (!uip_addr) {
			return NULL;
		}

		memcpy(&local_addr->in6_addr, &uip_addr->ipaddr,
		       sizeof(struct in6_addr));
	}
#else
	if (local_addr->in_addr.s_addr == INADDR_ANY) {
		uip_gethostaddr((uip_ipaddr_t *)&local_addr->in_addr);
	}
#endif

	nano_sem_take(&contexts_lock, TICKS_UNLIMITED);

	if (local_port) {
		if (context_port_used(ip_proto, local_port, local_addr) < 0) {
			return NULL;
		}
	} else {
		do {
			local_port = random_rand() | 0x8000;
		} while (context_port_used(ip_proto, local_port,
					   local_addr) == -EEXIST);
	}

	for (i = 0; i < NET_MAX_CONTEXT; i++) {
		if (!contexts[i].tuple.ip_proto) {
			contexts[i].tuple.ip_proto = ip_proto;
			contexts[i].tuple.remote_addr = (struct net_addr *)remote_addr;
			contexts[i].tuple.remote_port = remote_port;
			contexts[i].tuple.local_addr = (struct net_addr *)local_addr;
			contexts[i].tuple.local_port = local_port;
			context = &contexts[i];
			break;
		}
	}

	context_sem_give(&contexts_lock);

	/* Set our local address */
#ifdef CONFIG_NETWORKING_WITH_IPV6
	memcpy(&ipaddr.u8, local_addr->in6_addr.s6_addr, sizeof(ipaddr.u8));
	if (uip_is_addr_mcast(&ipaddr)) {
		uip_ds6_maddr_add(&ipaddr);
	} else {
		uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
	}
#endif

	return context;
}