Error on adl_smsSend PDU MODE but OK with AT commands

Hello,

I want to send an SMS with the PDU mode. The SMS is “TEST” sending to phone number “+33613271038”.
I use a FXT009 and its settings are:

With AT command, I have no problem:

But if I use the adl_smsSend API, the function returns -2 (bad parameters).

Here is the source code:

#include "adl_global.h"
#include "generated.h"


#define nTIMER_START_MAIN_EXECUTION_SEC		(10)

#define szPIN_CODE 							("0000")


s8 g_bSmsHandlePdu;
bool g_IsSmsPduInitialized;


static void At_PDU(adl_atCmdPreParser_t* pParams);
static void AtCommandSendOk(adl_port_e Port);
static void AtCommandSendError(adl_port_e Port);
static bool TestSendSmsPdu(void);







//-----------------------------------------------------------------------------
static bool TestSendSmsPdu(void)
//-----------------------------------------------------------------------------
{
	u8 ubData[] = {
		0x00,
		0x01, 0x00, 0x0B, 0x91, 0x33, 0x16, 0x23, 0x17, 0x30, 0xF8, 0x00, 0x00,	0x04,
		0xD4, 0xE2, 0x94, 0x0A
	};
	int nDataSize = sizeof(ubData)/sizeof(ubData[0]);

	if(g_bSmsHandlePdu < 0 || !g_IsSmsPduInitialized)
	{
		TRACE((1, "TestSendSmsPdu -> not initialized"));
		return FALSE;
	}

	DUMP(1, ubData, nDataSize);

	s8 bRes = adl_smsSend(g_bSmsHandlePdu, NULL, (ascii*)ubData, ADL_SMS_MODE_PDU);
	if(bRes == OK)
	{
		TRACE((1, "adl_smsSend PDU -> OK"));
	}
	else
	{
		TRACE((1, "adl_smsSend PDU -> ERROR %d", bRes));
	}

	return (bRes == OK);
}

//-----------------------------------------------------------------------------
static void At_PDU(adl_atCmdPreParser_t* pParams)
//-----------------------------------------------------------------------------
{
	TRACE((1, "At_PDU Type:0x%X", pParams->Type));

	bool boResult = TRUE;
	if(pParams->Type == ADL_CMD_TYPE_ACT)
	{
		if(!g_IsSmsPduInitialized)
		{
			TRACE((1, "At_SMS SMS PDU NOT initialized"));
			boResult = FALSE;
		}
		else
		{
			boResult = TestSendSmsPdu();
		}
	}
	else
	{
		boResult = FALSE;
	}

	(boResult ? AtCommandSendOk(pParams->Port) : AtCommandSendError(pParams->Port));
}

//-----------------------------------------------------------------------------
static void AtCommandSendOk(adl_port_e Port)
//-----------------------------------------------------------------------------
{
	TRACE((1, "AtCommandSendOk"));

	adl_atSendResponse(ADL_AT_PORT_TYPE((u8)(Port), ADL_AT_RSP), "\r\nOK\r\n");
}

//-----------------------------------------------------------------------------
static void AtCommandSendError(adl_port_e Port)
//-----------------------------------------------------------------------------
{
	TRACE((1, "AtCommandSendError"));

	adl_atSendResponse(ADL_AT_PORT_TYPE((u8)(Port), ADL_AT_RSP), "\r\nERROR\r\n");
}

//-----------------------------------------------------------------------------
static void SmsCtrlHandlerPDU(u8 ubEvent, u16 usNb)
//-----------------------------------------------------------------------------
{
	switch(ubEvent)
	{
	case ADL_SMS_EVENT_SENDING_OK:
		TRACE((1, "SmsCtrlHandlerPDU -> ADL_SMS_EVENT_SENDING_OK"));
	break;
	case ADL_SMS_EVENT_SENDING_ERROR:
		TRACE((1, "SmsCtrlHandlerPDU -> ADL_SMS_EVENT_SENDING_ERROR (%u)", usNb));
	break;
	case ADL_SMS_EVENT_SENDING_MR:
		TRACE((1, "SmsCtrlHandlerPDU -> ADL_SMS_EVENT_SENDING_MR (%u)", usNb));
	break;
	default:
		TRACE((1, "SmsCtrlHandlerPDU -> Unknown event %u", ubEvent));
	break;
	}
}

//-----------------------------------------------------------------------------
static bool SmsHandlerPDU(ascii* szSmsTel, ascii* szSmsTimeLength, ascii* szSmsText)
//-----------------------------------------------------------------------------
{
	ascii szLog[512];
	snprintf(szLog, 512, "SmsHandlerPDU: %s, %s, %s", szSmsTel, szSmsTimeLength, szSmsText);
	TRACE((1, szLog));
	return FALSE;
}

//-----------------------------------------------------------------------------
static void OnSimFullInit(void)
//-----------------------------------------------------------------------------
{
	TRACE((1, "OnSimFullInit"));

	g_bSmsHandlePdu = adl_smsSubscribe(SmsHandlerPDU, SmsCtrlHandlerPDU, ADL_SMS_MODE_PDU);
	if(g_bSmsHandlePdu < 0)
	{
		TRACE((1, "adl_smsSubscribe PDU Error %d", g_bSmsHandlePdu));
	}
	else
	{
		TRACE((1, "adl_smsSubscribe PDU -> OK Handle is %d", g_bSmsHandlePdu));
		g_IsSmsPduInitialized = TRUE;
	}
}

//-----------------------------------------------------------------------------
static void SimMessage(u8 Event)
//-----------------------------------------------------------------------------
{
	switch(Event)
	{
	case ADL_SIM_EVENT_REMOVED:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_REMOVED"));
	break;
	case ADL_SIM_EVENT_INSERTED:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_INSERTED"));
	break;

	case ADL_SIM_EVENT_FULL_INIT:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_FULL_INIT"));
		OnSimFullInit();
	break;

	case ADL_SIM_EVENT_PIN_ERROR:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_PIN_ERROR"));
	break;
	case ADL_SIM_EVENT_PIN_OK:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_PIN_OK"));
	break;

	case ADL_SIM_EVENT_PIN_WAIT:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_PIN_WAIT"));
	break;
	case ADL_SIM_EVENT_PUK_WAIT:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_PUK_WAIT"));
	break;

	case ADL_SIM_EVENT_PUK_ERROR:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_PUK_ERROR"));
	break;
	case ADL_SIM_EVENT_FAILURE:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_FAILURE"));
	break;
	case ADL_SIM_EVENT_NET_LOCK:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_NET_LOCK"));
	break;

	case ADL_SIM_EVENT_LAST:
		TRACE((1, "SimMessage -> ADL_SIM_EVENT_LAST"));
	break ;
	default:
		TRACE((1, "SimMessage -> Unknown event: %u", Event));
	break;
	}
}

//-----------------------------------------------------------------------------
static void StartMainExecutionTimerHandler(u8 ubId,  void* pContext)
//-----------------------------------------------------------------------------
{
	// Subscribe
	if(adl_simSubscribe(SimMessage, "0000") != OK)
	{
		TRACE((1, "SimManagerStart -> ERROR adl_simSubscribe"));
	}
}

//-----------------------------------------------------------------------------
void main_task(void)
//-----------------------------------------------------------------------------
{
	TRACE((1, "main_task"));

	adl_atCmdSubscribe("AT+PDU", At_PDU, ADL_CMD_TYPE_ACT);

	// Start the main execution with a timer
	adl_tmr_t* result = adl_tmrSubscribe(FALSE, 50,	ADL_TMR_TYPE_100MS,	(adl_tmrHandler_t)StartMainExecutionTimerHandler);
	if(result == NULL)
	{
		TRACE((1, "main_task -> ERROR adl_tmrSubscribe"));
	}
}

With AT command:

AT+CMGS=<length><CR>
> "PDU to be sent <Ctrl-Z>"
+CMGS: <mr>
OK

The DOES NOT include the first byte 0x00 which means SMSC number length is 0, so use the Service Center Address from AT+CSCA.
The data 0001000B913316231730F8000004D4E2940A is 18 bytes length but the length which is sent to AT+CMGS is 17.

With the adl_smsSend API, I convert a byte buffer into an ascii buffer. There is no ending 0 character in this ascii buffer but the first character is 0.
I don’t know how the adl_smsSend function manages this buffer.
If I remove the first character 0, I get the same error (bad parameters).

I will appreciate any help for this problem.

Just few remarks:

  • adl_smsSend API works fine in TEXT mode.
  • SmsHandlerPDU handler works fine if the FXT receives an SMS in PDU mode.

Thanks.
Marc

It is either a broken API or you need to convert your u8 array to hexcoded nullterminated string.
(ascii *) only typecasts, it does not convert.

So instead of

u8 ubData[] = {
          0x00,
          0x01, 0x00, 0x0B, 0x91, 0x33, 0x16, 0x23, 0x17, 0x30, 0xF8, 0x00, 0x00,   0x04,
          0xD4, 0xE2, 0x94, 0x0A
       };

It needs to be

ascii asciiData[]="0001000B9133...";

Hi,

I tested the case at my end. Given below the adl_smsSend API used over here.

s8 bRes = adl_smsSend(g_bSmsHandlePdu, NULL, “0001000A816968926181000004E8743A0D”, ADL_SMS_MODE_PDU);

The sms_text (0001000A816968926181000004E8743A0D) is generated using PduSpy tool which includes both the number where to send the sms and the sms text itself.

Please try at your end using the tool to create PDU message and pass it as a string directly to the adl_smsSend API.

Thanks.

OK, thanks Tobias for the solution.
Perhaps a little improvement into the documentation will help other developers…

Marc

I agree that the documentation isn’t exactly clear in the PDU case.
However, considering that adl_smsSend doesn’t take any length argument, the only thing that makes sense is a normal text string just as used when issuing commands manually.