# Using adl\_atCmdPreParser\_t to direct call custom AT handler

**URL:** <https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747>\
**Category:** Open AT\
**Created:** [July 21, 2012, 4:56am UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747 "2012-07-21T04:56:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![brettj](https://avatars.discourse-cdn.com/v4/letter/b/bbce88/32.png) [@brettj](https://forum.sierrawireless.com/u/brettj)\
**Post date:** [July 21, 2012, 4:56am UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747/1 "2012-07-21T04:56:40Z")

</div>

Hi All,

My first post. awneil, your posts are very helpful. Thanks for your effort.

I have solved many problems from previous posts and the OpenAT Framework Tutorial, but I am stuck on this issue. Sorry if this is a fundamental C programming question but I have spend many frustrating hours on this.

I want to run my custom AT command via SMS. I know the adl\_atCmdSend and adl\_atCmdCreate will not work so I am trying to call my command handler function directly. I cannot figure out how to load the adl\_atCmdPreParser\_t struct correctly.

I am using the following function to test with.

```auto
void Test_ATJE(void) {

	int i;
	ascii aOrig[200], aPar[50];

	static wm_lstTable_t ListTable = {
			(void*)NULL,
			(void*)NULL
	};

	adl_atCmdPreParser_t parms = {
		.StrData[0] = 0, // Incoming command address ??? I don't get this syntax ???
		.Type = ADL_CMD_TYPE_PARA,	// Type
		.NbPara = 0, // Number of parameters
		.Port = ADL_PORT_NONE, // Port
		.ParaList = wm_lstCreate(WM_LIST_NONE, &ListTable), // List of parameters
		.StrLength = 0, // Incoming command length
		.NI = 0, // Notification Identifier
		.Contxt = (void*)NULL // Context
	};

	adl_atCmdPreParser_t *ppars;

	sprintf(aOrig, "ATJE=10,20,30,40"); // My custom AT command test string
	//parms.StrData = aOrig; // ??? crashes ???
	sprintf(buff, "StrData[1] = %s", parms.StrData);
	TRACE(( 2, buff ));

	wm_lstClear(parms.ParaList);
	for ( i=0 ; ; i++ ) {
		if (wm_strGetParameterString(aPar, aOrig, i+1) == NULL)
			break;
		ret16 = wm_lstAddItem(parms.ParaList, (void*)aPar);
		if (ret16 == ERROR)
			sprintf(buff, "Add item %s ERRORed", aPar);
		else
			sprintf(buff, "Added item %s at position %d", aPar, ret16);
		TRACE((2, buff ));
	}
	sprintf(buff, "pars.ParaList membersB - 0=%s, 1=%s, 2=%s, 3=%s",
			(ascii*)wm_lstGetItem ( parms.ParaList, 0),
			(ascii*)wm_lstGetItem ( parms.ParaList, 1),
			(ascii*)wm_lstGetItem ( parms.ParaList, 2),
			(ascii*)wm_lstGetItem ( parms.ParaList, 3));
	TRACE((2,buff));

	ppars = &parms;
	sprintf(buff, "pars.ParaList membersA - 0=%s, 1=%s, 2=%s, 3=%s",
			ADL_GET_PARAM(ppars, 0),
			ADL_GET_PARAM(ppars, 1),
			ADL_GET_PARAM(ppars, 2),
			ADL_GET_PARAM(ppars, 3));
	TRACE((2,buff));

	parms.NbPara = (u8)wm_lstGetCount(parms.ParaList);
	sprintf(buff, "Total added items = %d", parms.NbPara);
	TRACE((2, buff ));

	parms.StrLength = strlen(aOrig);
	sprintf(buff, "pars.StrLength = %d", parms.StrLength);
	TRACE((2, buff ));

	if (strstr(aOrig, "ATJE?") > 0)
		parms.Type = ADL_CMD_TYPE_READ;
	if (strstr(aOrig, "ATJE=?") > 0)
		parms.Type = ADL_CMD_TYPE_TEST;

	ATJE_CMD_handler( &parms );
}
```

1. I don’t understand how ‘ascii StrData[1]’ can be used as a pointer as it is only one byte long. How do I use it to point to my string?

2. Am I doing the right thing by initializing parms, my instance of adl\_atCmdPreParser\_t?

3. Am I initializing and loading the wm\_lst\_t ParaList properly?

4. Should I be destroying anything before exiting this function?

Any assistance much appreciated.

---

<div class="post-metadata">

**Author:** ![awneil](https://avatars.discourse-cdn.com/v4/letter/a/49beb7/32.png) [@awneil](https://forum.sierrawireless.com/u/awneil)\
**Post date:** [July 21, 2012, 8:57am UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747/2 "2012-07-21T08:57:41Z")

</div>

> [@brettj](#):
>
> I want to run my custom AT command via SMS. I know the adl\_atCmdSend and adl\_atCmdCreate will not work

What version of Open-AT are you using?

Recent versions do have the facility to call custom AT commands from the application - don’t they ❓

> [@](#):
>
> so I am trying to call my command handler function directly

I wouldn’t do that.

Rather, I would have a “worker” function to actually do the work, and the command handler just parses the parameters from the user.

Your SMS handler would also do the parsing (there are library functions for this), and call the “worker” function.

> [@](#):
>
> I cannot figure out how to load the adl\_atCmdPreParser\_t struct correctly.

I’m not sure that it’s really sufficiently documented nor intended for you to do that.  
Hence the above suggestion.

> [@](#):
>
> 1. I don’t understand how ‘ascii StrData[1]’ can be used as a pointer as it is only one byte long. How do I use it to point to my string?

This is a standard ‘C’ programming trick for having a variable-length field at the end of a data structure.

---

<div class="post-metadata">

**Author:** ![brettj](https://avatars.discourse-cdn.com/v4/letter/b/bbce88/32.png) [@brettj](https://forum.sierrawireless.com/u/brettj)\
**Post date:** [July 21, 2012, 11:02am UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747/3 "2012-07-21T11:02:07Z")

</div>

Thanks for your quick response.

> [@awneil](#):
>
> What version of Open-AT are you using?

ati9 details are:  
“DWL”,“V08b11”,“”,“Sierra Wireless”,55236,“122210 15:25”,“e8a16b54”,“00010000”  
“FW”,“FW\_SRC\_746\_8.Q2687RDG”,“R7.46.0.201108091301.FXT009”,“Sierra Wireless”,2216044,“080911 13:01”,“2f1beedd”,“00020000”  
-“Developer Studio”,“2.2.0.201205091434-R9457”  
-“Open AT Embedded Software Suite package”,“2.34.0.201009090506”  
-“Open AT OS Package”,“6.34.0.201007281407”  
-“Firmware Package”,“7.44.0.201008311212”  
-“WIP Plug-in Package”,“5.40.0.201007290812”  
“ROM”,“800000”  
“RAM”,“200000”  
“DWLNAME”,“FXT009”

> [@awneil](#):
>
> Recent versions do have the facility to call custom AT commands from the application - don’t they

I was not aware of this. All I have to go on is previous posts and the Framework Tutorial document. This would be very convenient.

> [@awneil](#):
>
> I wouldn’t do that.
> 
> Rather, I would have a “worker” function to actually do the work, and the command handler just parses the parameters from the user.
> 
> Your SMS handler would also do the parsing (there are library functions for this), and call the “worker” function.

I receive an AT command string via SMS, and I have a very comprehensive custom AT command handler function that works great when AT command is entered in the normal way. But, in this scenario, I am not sure what the ‘command handler’ is that you refer to.

Up to this point, I have been parsing the user string with wm\_strGetParameterString and processing it manually with a function that effectively duplicated all the functionality of my custom command handler. It worked, but seemed very inefficient, so I was looking for a better way.

> [@](#):
>
> I cannot figure out how to load the adl\_atCmdPreParser\_t struct correctly.

> [@awneil](#):
>
> I’m not sure that it’s really sufficiently documented nor intended for you to do that.  
> Hence the above suggestion.

I am more than happy not to do it if there is a better way 🙂

> [@](#):
>
> 1. I don’t understand how ‘ascii StrData[1]’ can be used as a pointer as it is only one byte long. How do I use it to point to my string?

> [@awneil](#):
>
> This is a standard ‘C’ programming trick for having a variable-length field at the end of a data structure.

Yes, I get this. I reserve a chunk of memory the sizeof(adl\_atCmdPreParser\_t) plus the length of my string. Put the struct at the start and copy in my string at &StrData[0]. I am sure I could get this to work. Although it is a moot point if I can just use my custom AT command handler.

Thanks for bearing with me, I am on a pretty steep learning curve here.

---

<div class="post-metadata">

**Author:** ![awneil](https://avatars.discourse-cdn.com/v4/letter/a/49beb7/32.png) [@awneil](https://forum.sierrawireless.com/u/awneil)\
**Post date:** [July 21, 2012, 12:56pm UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747/4 "2012-07-21T12:56:22Z")

</div>

> [@brettj](#):
>
> All I have to go on is previous posts and the Framework Tutorial document.

You need to look in the ADL User Guide.

Don’t have mine to hand, but look for a …CommandSubscribeExt… function, or similar

> [@](#):
>
> I am not sure what the ‘command handler’ is that you refer to.

The thing that you actually specified in the subscription.

> [@](#):
>
> Up to this point, I have been parsing the user string with wm\_strGetParameterString and processing it manually with a function that effectively duplicated all the functionality of my custom command handler.

So just take the duplicate functionality out into a separate function. And call that function from both your SMS handler and your custom AT command handler

---

<div class="post-metadata">

**Author:** ![brettj](https://avatars.discourse-cdn.com/v4/letter/b/bbce88/32.png) [@brettj](https://forum.sierrawireless.com/u/brettj)\
**Post date:** [July 22, 2012, 8:00am UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747/5 "2012-07-22T08:00:51Z")

</div>

I did what you suggested and got it all working. I do know what a command handler is, I just was not sure which one you were referring to.

Thanks for your assistance.

---

<div class="post-metadata">

**Author:** ![Jeroen1](https://avatars.discourse-cdn.com/v4/letter/j/47e85d/32.png) [@Jeroen1](https://forum.sierrawireless.com/u/Jeroen1)\
**Post date:** [July 22, 2012, 6:06pm UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747/6 "2012-07-22T18:06:09Z")

</div>

> [@brettj](#):
>
> Hi All,  
> I want to run my custom AT command via SMS. I know the adl\_atCmdSend and adl\_atCmdCreate will not work so I am trying to call my command handler function directly. I cannot figure out how to load the adl\_atCmdPreParser\_t struct correctly.

fyi, outdated, but I met the same problem quite a while ago, 2009 or so? This [github.com/jhofstee/siwi2way/bl … ls/ve\_at.c](https://github.com/jhofstee/siwi2way/blob/master/src/utils/ve_at.c) is the same workaround as you suggested. The advantage of it is that it will also work without linking to siwi libs, e.g. a standalone simulator, but perhaps the RTE actually works nowadays.

Regards,  
Jeroen

---

<div class="post-metadata">

**Author:** ![brettj](https://avatars.discourse-cdn.com/v4/letter/b/bbce88/32.png) [@brettj](https://forum.sierrawireless.com/u/brettj)\
**Post date:** [July 23, 2012, 12:16pm UTC](https://forum.sierrawireless.com/t/using-adl-atcmdpreparser-t-to-direct-call-custom-at-handler/5747/7 "2012-07-23T12:16:32Z")

</div>

Thanks for your response and the link Jeroen. I got it working by basically doing what awneil suggested.

Apparently the latest version of OpenAT will allow me to call my own custom AT commands. But I admit, I am a bit confused about all the different software blocks and tools involved, how they relate and what is compatible with what, let alone am I running the latest version of them all.

But I am loving the learning. I read on and always stumble across the answer eventually.

Cheers
