RUI3 execute AT command from downlink messsage

We have several custom AT commands developed in RUI3 and would like to execute those AT commands from a lora downlink message. Is there an api call to do that in RUI3, we didn’t see any in the documenation. If not, is there some way we could make a call into the underlying AT command parser and send it the downlink message messsage and have the existing AT command logic parse and process it just as if it came from the uart?

Not sure if I understand correct.

You want to send (custom) AT commands as downlinks as text?

Right now there is no API call to forward text into the AT command parser.

All “standard” AT commands are mirrored as API calls. So instead of sending a text, why don’t you send the command and parameter as binary data and then parse the download and use the API calls?

For custom AT commands this could be handled similar. Here is a code snippet how I would implement it:

/**
 * @brief Callback after packet was received
 *
 * @param data Structure with the received data
 */
void receiveCallback(SERVICE_LORA_RECEIVE_T *data)
{
	uint32_t new_value;

	// Parse the incoming command
	switch (data->Buffer[0])
	{
	// Change send interval (custom AT command)
	case 0x01:
		new_value |= data->Buffer[1] << 0;
		new_value |= data->Buffer[2] << 8;
		new_value |= data->Buffer[3] << 16;
		new_value |= data->Buffer[4] << 24;
		save_and_set_sendfreq(new_value);
		break;
	// Change data rate (standard AT command)
	case 0x02:
		new_value |= data->Buffer[1];
		api.lorawan.dr.set(new_value);
		break;
	// Other commands
	default:
		break;
	}
}

/**
 * @brief Handler for send frequency AT commands
 *
 * @param port Serial port used
 * @param cmd char array with the received AT command
 * @param param char array with the received AT command parameters
 * @return int result of command parsing
 * 			AT_OK AT command & parameters valid
 * 			AT_PARAM_ERROR command or parameters invalid
 */
int interval_send_handler(SERIAL_PORT port, char *cmd, stParam *param)
{
	if (param->argc == 1 && !strcmp(param->argv[0], "?"))
	{
		Serial.print(cmd);
		Serial.printf("=%lds\r\n", g_send_repeat_time / 1000);
	}
	else if (param->argc == 1)
	{
		for (int i = 0; i < strlen(param->argv[0]); i++)
		{
			if (!isdigit(*(param->argv[0] + i)))
			{
				return AT_PARAM_ERROR;
			}
		}

		uint32_t new_send_freq = strtoul(param->argv[0], NULL, 10);

		g_send_repeat_time = new_send_freq * 1000;

		save_and_set_sendfreq(g_send_repeat_time);
	}
	else
	{
		return AT_PARAM_ERROR;
	}

	return AT_OK;
}

/**
 * @brief Save and set new send interval
 * 
 * @param new_interval new interval time in milliseconds
 */
void save_and_set_sendfreq(uint32_t new_interval)
{
	// Stop the timer
	api.system.timer.stop(RAK_TIMER_0);
	if (g_send_repeat_time != 0)
	{
		// Restart the timer
		api.system.timer.start(RAK_TIMER_0, g_send_repeat_time, NULL);
	}
	// Save custom settings
	save_at_setting();
}

Thanks Bernd, that solution will work fine…