Commit dc6e7aa4 authored by Seppo Takalo's avatar Seppo Takalo Committed by Fabio Baltieri
Browse files

net: lwm2m: Add transmission state indicator to RX as well



Refactored the socket state indication into its own function
that checks the state of TX queues as well as number of
pending CoAP responses.
Check the state after receiving a packet, as it might
have been a last Ack packet we have been waiting.

Signed-off-by: default avatarSeppo Takalo <seppo.takalo@nordicsemi.no>
parent ba80bc71
Loading
Loading
Loading
Loading
+47 −25
Original line number Diff line number Diff line
@@ -630,6 +630,50 @@ cleanup:
	return next;
}

/**
 * @brief Check TX queue states as well as number or pending CoAP transmissions.
 *
 * If all queues are empty and there is no packet we are currently transmitting and no
 * CoAP responses (pendings) we are waiting, inform the application by a callback
 * that socket is in state LWM2M_SOCKET_STATE_NO_DATA.
 * Otherwise, before sending a packet, depending on the state of the queues, inform with
 * one of the ONGOING, ONE_RESPONSE or LAST indicators.
 *
 * @param ctx Client context.
 * @param ongoing_tx Current packet to be transmitted or NULL.
 */
static void hint_socket_state(struct lwm2m_ctx *ctx, struct lwm2m_message *ongoing_tx)
{
	if (!ctx->set_socket_state) {
		return;
	}

#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
	bool empty = sys_slist_is_empty(&ctx->pending_sends) &&
		     sys_slist_is_empty(&ctx->queued_messages);
#else
	bool empty = sys_slist_is_empty(&ctx->pending_sends);
#endif
	size_t pendings = coap_pendings_count(ctx->pendings, ARRAY_SIZE(ctx->pendings));

	if (ongoing_tx) {
		/* Check if more than current TX is in pendings list*/
		if (pendings > 1) {
			empty = false;
		}

		if (!empty) {
			ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_ONGOING);
		} else if (ongoing_tx->type == COAP_TYPE_CON) {
			ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_ONE_RESPONSE);
		} else {
			ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_LAST);
		}
	} else if (empty && pendings == 0) {
		ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_NO_DATA);
	}
}

static int socket_recv_message(struct lwm2m_ctx *client_ctx)
{
	static uint8_t in_buf[NET_IPV6_MTU];
@@ -684,31 +728,7 @@ static int socket_send_message(struct lwm2m_ctx *ctx)
		coap_pending_cycle(msg->pending);
	}

	if (ctx->set_socket_state) {
#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED)
		bool empty = sys_slist_is_empty(&ctx->pending_sends) &&
			     sys_slist_is_empty(&ctx->queued_messages);
#else
		bool empty = sys_slist_is_empty(&ctx->pending_sends);
#endif
		if (coap_pendings_count(ctx->pendings, ARRAY_SIZE(ctx->pendings)) > 1) {
			empty = false;
		}

		if (!empty) {
			ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_ONGOING);
		} else {
			switch (msg->type) {
			case COAP_TYPE_CON:
				ctx->set_socket_state(ctx->sock_fd,
						      LWM2M_SOCKET_STATE_ONE_RESPONSE);
				break;
			default:
				ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_LAST);
				break;
			}
		}
	}
	hint_socket_state(ctx, msg);

	rc = zsock_send(msg->ctx->sock_fd, msg->cpkt.data, msg->cpkt.offset, 0);

@@ -847,6 +867,8 @@ static void socket_loop(void *p1, void *p2, void *p3)
						break;
					}
				}

				hint_socket_state(sock_ctx[i], NULL);
			}

			if (sock_fds[i].revents & ZSOCK_POLLOUT) {