how do I send an sms?

I tried this but it didn’t work.

/* file: main.c */
#include "adl_global.h"
#include "generated.h"

/* variables */
static s8 sms_automaton_Handle_txt;

void SMS_AUTO_ctrl_Handler(u8 Event, u16 Nb)
{
    // Does nothing
}

bool SMS_AUTO_Handler(ascii *SmsTel, ascii *SmsTimeOrLength, ascii *SmsText)
{
    return FALSE;
}

void main_task ( void )
{
    // Subscribe to the SMS Service
    sms_automaton_Handle_txt = adl_smsSubscribe(SMS_AUTO_Handler, SMS_AUTO_ctrl_Handler, ADL_SMS_MODE_TEXT);
    adl_smsSend(sms_automaton_Handle_txt, "+628813227153", "SMS test", ADL_SMS_MODE_TEXT);
}

Rule 1 in any form of programming:

Never ignore the return values from API calls!

ok, the adl_smsSubscribe return successfully but the adl_smsSend said that “initialization not yet
performed, or sending an SMS already in progress” (ADL_RET_ERR_BAD_STATE).
what does it mean?
if I should perform some initialization, what initialization should I perform?
is it about mandatory API?
I’ve search about mandatory API chapter but I couldn’t find it.

product is not ready to send an SMS
(initialization not yet performed, or sending an SMS already in
progress)

Here initialization implies GSM network registration . Check you are sending SMS after complete registration of network, also wait until last SMS has been sent.

by using adl_simSubscribe function?

Study the documentation for the adl_simSubscribe function - does it give you all the information necessary to know when the unit is ready to send an SMS…?

Take a look through the FAQ/Wiki thread - in particular: viewtopic.php?f=7&t=3766&start=15#p17708

here’s my code at the moment:

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

/* variables */
static s8 sms_automaton_Handle_txt;

void SMS_AUTO_ctrl_Handler(u8 Event, u16 Nb)
{
    switch (Event) {
    case ADL_SMS_EVENT_SENDING_ERROR:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nSMS_AUTO_ctrl_Handler(): ADL_SMS_EVENT_SENDING_ERROR\r\n");
    	break;
    case ADL_SMS_EVENT_SENDING_MR:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nSMS_AUTO_ctrl_Handler(): ADL_SMS_EVENT_SENDING_MR\r\n");
    	break;
    default:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nSMS_AUTO_ctrl_Handler(): OK\r\n");
    	break;
    }
}

bool SMS_AUTO_Handler(ascii *SmsTel, ascii *SmsTimeOrLength, ascii *SmsText)
{
	ascii *foo = (ascii*)adl_memGet(50);

	if (foo != NULL) {
		wm_strcpy(foo, "\r\n");
		wm_strcpy(foo, SmsTel);
		wm_strcat(foo, " ");
		wm_strcat(foo, SmsText);
		wm_strcat(foo, "\r\n");
		adl_atSendResponse(ADL_AT_UNS, foo);
		adl_memRelease(foo);
	} else {
		adl_atSendResponse(ADL_AT_UNS, "\r\nout of memory.\r\n");
	}

    return FALSE;
}

void sim_Hdlr (u8 ev)
{
}

void main_task ( void )
{
    // Subscribe to the SMS Service
    sms_automaton_Handle_txt = adl_smsSubscribe(SMS_AUTO_Handler, SMS_AUTO_ctrl_Handler, ADL_SMS_MODE_TEXT);

    switch (adl_simSubscribe(sim_Hdlr, NULL)) {
    case ADL_RET_ERR_SERVICE_LOCKED:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_simSubscribe(): ADL_RET_ERR_SERVICE_LOCKED\r\n");
    	break;
    case ADL_RET_ERR_ALREADY_SUBSCRIBED:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_simSubscribe(): ADL_RET_ERR_ALREADY_SUBSCRIBED\r\n");
    	break;
    case ADL_RET_ERR_PARAM:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_simSubscribe(): ADL_RET_ERR_PARAM\r\n");
    	break;
    default:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_simSubscribe(): OK\r\n");
    	break;
    }

    switch (sms_automaton_Handle_txt) {
    case ADL_RET_ERR_PARAM:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSubscribe(): ADL_RET_ERR_PARAM\r\n");
    	break;
    case ADL_RET_ERR_SERVICE_LOCKED:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSubscribe(): ADL_RET_ERR_SERVICE_LOCKED\r\n");
    	break;
    default:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSubscribe(): OK\r\n");
    	break;
    }

    switch (adl_smsSend(sms_automaton_Handle_txt, "+628813227153", "SMS test", ADL_SMS_MODE_TEXT)) {
    case ADL_RET_ERR_PARAM:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_PARAM\r\n");
    	break;
    case ADL_RET_ERR_UNKNOWN_HDL:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_UNKNOWN_HDL\r\n");
    	break;
    case ADL_RET_ERR_BAD_STATE:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_BAD_STATE\r\n");
    	break;
    case ADL_RET_ERR_SERVICE_LOCKED:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_SERVICE_LOCKED\r\n");
    	break;
    default:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): OK\r\n");
    	break;
    }
}

and here’s the result:

Where in the code do you check to see that the unit is ready to send an SMS :question:

I have no idea how to do it.

Hi
In your code make sure you wait for the specific +WIND indications before performing your operation.
In this case you need to wait for +WIND:16 indication(which specifies that SMS and SMS CB services have been initialized).

Regards
Paruthiv

No - there isn’t a specific +WIND: indication for this.

This is necessary, but not sufficient.

This just indicates that the initialisation is complete on the module - it does not indicate that the module is GSM-Registered!

Again, the OP needs to spend time studying the AT Commands Guide to look at what commands & indications are available.

Specifically, AT+CREG queries the current registration state - and can be used to enable unsolicited indication when the state changes.

So the unit can either use AT+CREG to specifically check - or “poll” - the current registration state, or use the unsolicited notifications to maintain its own record of the state.

The ADL User Guide tells how to issue AT Commands, and how to monitor (or “subscribe” to) unsolicited indications.

thanks

it’s still not working.
here’s my code:

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

void SMS_AUTO_ctrl_Handler(u8 Event, u16 Nb)
{
	adl_atSendResponse(ADL_AT_UNS, "\r\nSMS_AUTO_ctrl_Handler()\r\n");
    switch (Event) {
    case ADL_SMS_EVENT_SENDING_ERROR:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nSMS_AUTO_ctrl_Handler(): ADL_SMS_EVENT_SENDING_ERROR\r\n");
    	break;
    case ADL_SMS_EVENT_SENDING_MR:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nSMS_AUTO_ctrl_Handler(): ADL_SMS_EVENT_SENDING_MR\r\n");
    	break;
    default:
    	adl_atSendResponse(ADL_AT_UNS, "\r\nSMS_AUTO_ctrl_Handler(): OK\r\n");
    	break;
    }
}

bool SMS_AUTO_Handler(ascii *SmsTel, ascii *SmsTimeOrLength, ascii *SmsText)
{
	ascii *foo = (ascii*)adl_memGet(50);

	if (foo != NULL) {
		wm_strcpy(foo, "\r\n");
		wm_strcpy(foo, SmsTel);
		wm_strcat(foo, " ");
		wm_strcat(foo, SmsText);
		wm_strcat(foo, "\r\n");
		adl_atSendResponse(ADL_AT_UNS, foo);
		adl_memRelease(foo);
	} else {
		adl_atSendResponse(ADL_AT_UNS, "\r\nout of memory.\r\n");
	}

    return FALSE;
}

bool unso_hdlr (adl_atUnsolicited_t *param)
{
	s8 sms_automaton_Handle_txt = adl_smsSubscribe(SMS_AUTO_Handler, SMS_AUTO_ctrl_Handler, ADL_SMS_MODE_TEXT);

	adl_atSendResponse(ADL_AT_UNS, "\r\nunso_hdlr(): OK\r\n");

	switch (adl_smsSend(sms_automaton_Handle_txt, "+628813227153", "SMS test", ADL_SMS_MODE_TEXT)) {
	case ADL_RET_ERR_PARAM:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_PARAM\r\n");
		break;
	case ADL_RET_ERR_UNKNOWN_HDL:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_UNKNOWN_HDL\r\n");
		break;
	case ADL_RET_ERR_BAD_STATE:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_BAD_STATE\r\n");
		break;
	case ADL_RET_ERR_SERVICE_LOCKED:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): ADL_RET_ERR_SERVICE_LOCKED\r\n");
		break;
	default:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_smsSend(): OK\r\n");
		break;
	}

	return(TRUE);
}

void main_task ( void )
{
    // TODO Insert your task initialization code here
	switch (adl_atUnSoSubscribe("+CREG: 1", unso_hdlr)) {
	case OK:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_atUnSoSubscribe(): OK\r\n");
		break;
	case ERROR:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_atUnSoSubscribe(): ERROR\r\n");
		break;
	case ADL_RET_ERR_SERVICE_LOCKED:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_atUnSoSubscribe(): ADL_RET_ERR_SERVICE_LOCKED\r\n");
		break;
	default:
		adl_atSendResponse(ADL_AT_UNS, "\r\nadl_atUnSoSubscribe(): unknown error\r\n");
		break;
	}
}

and here’s the result:

any suggestion?

Have you worked through the SW example code?

Really?

What you showed there doesn’t match the code that you posted - does it?

And what did I say about ignoring the return values from API calls…?

the example is for incoming sms

I entered the command “AT+CREG=1” manually if that’s what you mean.

if I had to conclude what to do (the steps) to send a single sms after reading some hundreds of pages of a manual (or two), well I have to admit that I’m not that smart sir.

This is the output that you showed:

This is the start of the code that you showed:

void main_task ( void )
{
    // TODO Insert your task initialization code here
   switch( adl_atUnSoSubscribe("+CREG: 1", unso_hdlr) ) {
   case OK:
      adl_atSendResponse( ADL_AT_UNS, 
      "\r\nadl_atUnSoSubscribe(): OK\r\n");
      break;

   case ERROR:
      adl_atSendResponse( ADL_AT_UNS, 
      "\r\nadl_atUnSoSubscribe(): ERROR\r\n");
      break;

   case ADL_RET_ERR_SERVICE_LOCKED:
      adl_atSendResponse( ADL_AT_UNS, 
      "\r\nadl_atUnSoSubscribe(): ADL_RET_ERR_SERVICE_LOCKED\r\n");
      break;

   default:
      adl_atSendResponse( ADL_AT_UNS, 
      "\r\nadl_atUnSoSubscribe(): unknown error\r\n");
      break;
   }
}

None of those outputs appears in your picture, so I think it’s fair to say that the picture doesn’t match the code!

In your unso_hdlr, you use the handle value before checking that it is valid:

bool unso_hdlr( adl_atUnsolicited_t *param )
{
   s8 sms_automaton_Handle_txt = adl_smsSubscribe( SMS_AUTO_Handler, 
                                     SMS_AUTO_ctrl_Handler, ADL_SMS_MODE_TEXT );

   adl_atSendResponse( ADL_AT_UNS, "\r\nunso_hdlr(): OK\r\n" );

   switch
   ( 
       adl_smsSend
       ( 
           sms_automaton_Handle_txt, // you haven't checked this!
           "+628813227153", 
           "SMS test", 
           ADL_SMS_MODE_TEXT
       ) 
   ) 
   {

never mind, I finally figure it out. but thanks anyway.

I just wish there are some tutorials for a non-scientist person like me.

So how about you conclude this thread by explaining what you did to get it going?
That would benefit the next “non-scientist” to come along with the same question.

But what is it that you think is so “scientific” about this?

Programming is, in its very nature, a discipline that requires careful analysis, design and attention to detail. Not everyone is cut out to be a programmer…