At+wmbs from within openat


#1

Hello,

in my application I want to change the band, only if necessary. So first I request the current setting of AT+WMBS?. And then if the response != to which setting I want, I’ll change it and reboot the modem.

The question is: is it necessary to wait for the response of AT+WMBS=7,0 before sending AT+CFUN=1? In other words, is adl_atCmdSend queing, or executing directly?

thank you, Matthijs

Herewith the code:

void somefunction()
{
  // Request the current network band.
  adl_atCmdSend("AT+WMBS?", wmbsHandler, "+WMBS:", NULL);
}

bool wmbsHandler(adl_atResponse_t* parms)
{
  char* temp = ve_malloc(parms->StrLength);
  u8 currentBand;
  
  // The first parameter is the current band
  wm_strGetParameterString(temp, parms->StrData, 1);
  currentBand = atoi(temp);
	
  if (band != dev_regs.gsmUserBand)
  {
    // Set the network band.
    Str command;
		
    str_new(&command, 11, 1);
    str_addf(&command, "AT+WMBS=%d,0", band);
    adl_atCmdSend(command.data, NULL, NULL);

    str_free(&command);
  }
	
  // Reboot. (CAN THIS BE DONE IMMEDIATELY?)
  adl_atCmdSend("AT+CFUN=1", NULL, NULL);

  return false;
}

#2

If you don’t want to wait for response it’s better to concatenate the commands.
AT+WMBS=%d,0;+CFUN=1

Otherwise it’s usually better to wait for an OK response before new command.


#3

I would say that you should always wait for the response before sending any new command - it is the only way to know that the command has been accepted and actioned without error :exclamation:


#4

As long as the commands don’t belong to the same “class”, there are cases where you might want to issue more commands before getting a response.

For example +COPS can take a long time to get back with a response, and while that is running you can issue non-related commands safely and it might be desirable to run other commands during the time you are waiting for response to save time.

I agree however that you should have a response handler for all issued commands so that any error cases can be handled. Even for commands that “always succeeds”.


Normally we also have timers running to make sure we get responses within a reasonable time.


#5

Hello Gentlemen,

thank you for the replies. The ; to concatenate commands is new for me, very usefull. But in this case it is probably best to check for an error. Otherwise, when my application tries to set band 8, which doesn’t exist, it would end up being in a reset loop.

Best regards, Matthijs

ps. the code how it ended up. By the way, what a mess it creates, this event driven programming! 100 lines of code and 3 callbacks to change the frequency.

/**
 * Callback function for handling AT+WMBS= ..  response
 * 
 * After setting the band with "AT+WMBS=[band],0" the modem needs to be rebooted to activate the new band
 */
veBool wmbsSetLaterHandler(adl_atResponse_t* rsp)
{
	if (strcmp(rsp->StrData, "OK") != 0)
	{
		
    	ve_qtrace("Response to AT+WMBS=[band],0 was not OK: '%s'. Stop trying to change the band", rsp->StrData);

	} else {
		
		ve_qtrace("Response to AT+WMBS=[band],0 was OK. Reboot to activate new setting");
		adl_atCmdSend("AT+CFUN=1", NULL, NULL);
	}
	
	return veFalse;
}

/**
 * Callback function for handling AT+WMBS= ..  response
 */
veBool wmbsSetNowHandler(adl_atResponse_t* rsp)
{
	if (strcmp(rsp->StrData, "OK") != 0)
	{
    	Str command;
		GsmBand band = dev_regs.gsmUserBand;
		
    	ve_qtrace("Response to AT+WMBS=[band],1 was ERROR. Set it with ,0 parameter");

		if (band == GSM_BAND_DEFAULT)
		  band = dev_regs.gsmDefaultBand;

		// Apparently we couldn't set it right now. Set it the slow way
		// and have the reboot-callback called when done. 
		str_new(&command, 11, 1);
		str_addf(&command, "AT+WMBS=%d,0", band);
		adl_atCmdSend(command.data, wmbsSetLaterHandler, "*", NULL);
		
		str_free(&command);
	} else {
		
		ve_qtrace("Response to AT+WMBS=[band],1 was OK. New frequency band set successfully");

	}
	
	return veFalse;
}

/**
 * Callback function for handling AT+WMBS? response
 */
veBool wmbsGetHandler(adl_atResponse_t* parms)
{
	char* temp = ve_malloc(parms->StrLength);
	u8 currentBand;
	GsmBand band = dev_regs.gsmUserBand;

	// The first parameter is the current band
	wm_strGetParameterString(temp, parms->StrData, 1);
	currentBand = atoi(temp);

	ve_free(temp);
	
	if (band == GSM_BAND_DEFAULT)
		band = dev_regs.gsmDefaultBand;

	if (band != currentBand)
	{
		// Set the network band.
		Str command;

		ve_qtrace("Current band (%d) != requested band (%d). Change band and reboot afterwards", currentBand, band);

		str_new(&command, 11, 1);
		str_addf(&command, "AT+WMBS=%d,1", band);
		adl_atCmdSend(command.data, wmbsSetNowHandler, "*", NULL);

		str_free(&command);
  	} else {
  		ve_qtrace("Current band == requested band (%d)", currentBand);	
  	}

	return veFalse;
}

/*
 * Initialise the GSM handler, called at startup
 */
void comm_gsmInit(void)
{
	// Request the current network band.
	adl_atCmdSend("AT+WMBS?", wmbsGetHandler, "+WMBS:", NULL);

#6

Assuming you are using firmware that supports it, why not use WMBS=7?


#7

Hi Tobias,

yes, you are right. I already made change to put all new products on AT+WMBS=7 by default. But as these units are really everywhere (all over africa, etc.), I want to keep the option to change it. You never know if the siwi AT+WMBS=7 implementation is not perfect.

Matthijs