# Is Cellular.command Thread safe?

**URL:** <https://community.particle.io/t/is-cellular-command-thread-safe/52860>\
**Category:** Firmware\
**Tags:** electron\
**Created:** [October 22, 2019, 1:30pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860 "2019-10-22T13:30:15Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![wesner0019](https://avatars.discourse-cdn.com/v4/letter/w/0ea827/32.png) [@wesner0019](https://community.particle.io/u/wesner0019)\
**Post date:** [October 22, 2019, 1:30pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/1 "2019-10-22T13:30:15Z")

</div>

Is Cellular.command thread safe? If not does what would be needed to make it thread safe?

Thanks

---

<div class="post-metadata">

**Author:** ![rickkas7](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/rickkas7/32/8681_2.png) [@rickkas7](https://community.particle.io/u/rickkas7)\
**Post date:** [October 22, 2019, 2:10pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/2 "2019-10-22T14:10:53Z")

</div>

You can call Celluar.command from a worker thread. The caveat is that the modem is protected by a mutex, so if the system is using the modem (including during connecting to the cloud), the Cellular.command won’t execute until it’s done. This can take up to 5 minutes. Also if you’re issuing a different modem command from the application/loop thread, that would also block preventing your worker thread from continuing until the loop thread was done executing its modem command.

---

<div class="post-metadata">

**Author:** ![ahk](https://avatars.discourse-cdn.com/v4/letter/a/e56c9b/32.png) [@ahk](https://community.particle.io/u/ahk)\
**Post date:** [October 22, 2019, 5:42pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/3 "2019-10-22T17:42:22Z")

</div>

Sometimes even the particle functions that handle cell connectivity block the main loop. Even in system\_mode manual and threading enabled the loop stops running because “something” (not the user code) is executing AT commands… Not a good thing.

---

<div class="post-metadata">

**Author:** ![wesner0019](https://avatars.discourse-cdn.com/v4/letter/w/0ea827/32.png) [@wesner0019](https://community.particle.io/u/wesner0019)\
**Post date:** [October 24, 2019, 4:28pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/4 "2019-10-24T16:28:28Z")

</div>

@rickkas7 Is there any way to know when the system is using the modem? This would be useful to know so that I would only issue Celluar. command when it’s free to prevent any blocked code execution.

Right now I’m using the below code, but from the above this could get blocked if the system is trying to send data and then the below gets called.

```auto
void PublishQueueAsync::getRSSI() {
	#if PLATFORM_ID == PLATFORM_ELECTRON_PRODUCTION
	static uint32_t prevgetRSSIMillis = 0;
	char response[10] = "";
	response[0] = 0;
	if (millis() - prevgetRSSIMillis >= 15000 && millis() > 5000){
		if (Particle.connected() && Cellular.ready()) {
			CellularSignal sig = Cellular.RSSI();
			wirelessRSSI = sig.rssi;
				
			if (String(mode5).compareTo("MODE_5_DISABLED") == 0 && millis() > 25000) {
				if (RESP_OK == Cellular.command("AT+UCGED=5\r\n")) {
					mode5[0] = 0; 
				}
			}

			rsrp[0] = 0; //resets the array
			if (RESP_OK == Cellular.command(callbackUCGED, response, 200, "AT+UCGED?\r\n")) {
			} else {
				earfcn = 0;
				rsrp[0] = 0; //resets the array
			}
			//Serial.println(rsrp);
		} else {
			wirelessRSSI = 0;
			earfcn = 0;
			rsrp[0] = 0; //resets the array
		}

		prevgetRSSIMillis = millis();
	}
	#endif
}

```

---

<div class="post-metadata">

**Author:** ![wesner0019](https://avatars.discourse-cdn.com/v4/letter/w/0ea827/32.png) [@wesner0019](https://community.particle.io/u/wesner0019)\
**Post date:** [October 24, 2019, 4:32pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/5 "2019-10-24T16:32:45Z")

</div>

I just added the below (if (!haveEvent), to prevent this but I think this is a bad work around.

```auto
if (!haveEvent) {	
				if (String(mode5).compareTo("MODE_5_DISABLED") == 0 && millis() > 25000) {
					if (RESP_OK == Cellular.command("AT+UCGED=5\r\n")) {
						mode5[0] = 0; 
					}
				}

				rsrp[0] = 0; //resets the array
				if (RESP_OK == Cellular.command(callbackUCGED, response, 200, "AT+UCGED?\r\n")) {
				} else {
					earfcn = 0;
					rsrp[0] = 0; //resets the array
				}
			}

```

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [October 24, 2019, 4:44pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/6 "2019-10-24T16:44:29Z")

</div>

@wesner0019, ideally you would be able to test the mutex used by the DeviceOS which I will leave to @rickkas7 to help you with.

One note though is that you may want to NOT use String() in `if (String(mode5).compareTo("MODE_5_DISABLED") == 0`so as to avoid heap fragmentation. Instead, you should use `if (strcmp(mode5, "MODE_5_DISABLED") == 0` assuming `mode5` is a NULL terminated char array.

---

<div class="post-metadata">

**Author:** ![wesner0019](https://avatars.discourse-cdn.com/v4/letter/w/0ea827/32.png) [@wesner0019](https://community.particle.io/u/wesner0019)\
**Post date:** [October 24, 2019, 4:49pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/7 "2019-10-24T16:49:50Z")

</div>

@peekay123  
mode 5 is used as below. Is there a way I can make it NULL terminated?

```auto
char mode5[20]; 

```

```auto
int callbackUCGED(int type, const char* buf, int len, char* response) {

// buf format:+RSRP: 162,5110,"-075.00",

sscanf(buf, "\r\n+RSRP: %*d,%d,\"%s\",\r\n", &amp;earfcn, rsrp);
sscanf(buf, "\r\n+UCGED: %s \r\n", mode5);
if (earfcn &gt;= 600 &amp;&amp; earfcn &lt;=1199) earfcn = 2; //1900Mhz
else if (earfcn &gt;= 1950 &amp;&amp; earfcn &lt;=2399) earfcn = 4; //1700Mhz
else if (earfcn &gt;= 5010 &amp;&amp; earfcn &lt;=5179) earfcn = 12; //700Mhz
else if (earfcn == 65535) earfcn = 0; //not known or not detectable
return WAIT;
}

```

---

<div class="post-metadata">

**Author:** ![rickkas7](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/rickkas7/32/8681_2.png) [@rickkas7](https://community.particle.io/u/rickkas7)\
**Post date:** [October 24, 2019, 4:50pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/8 "2019-10-24T16:50:33Z")

</div>

We do recommend running Particle.publish calls and Cellular.RSSI(), or direct calls to AT+UCGED, in a worker thread to minimize disruption if they block. Often they can share a thread, or you can use a dedicated thread to only doing RSSI.

You can check Particle.connected() from your worker thread before calling Cellular.command(). This eliminates the most common cause of blocking that occurs during connecting to cellular. If you are not using the Particle cloud you can use Cellular.ready() instead.

It still could block for 5 seconds, but at least not 5 minutes. And since it’s in a dedicated thread it wouldn’t block the rest of your code so other things will still stay responsive.

---

<div class="post-metadata">

**Author:** ![wesner0019](https://avatars.discourse-cdn.com/v4/letter/w/0ea827/32.png) [@wesner0019](https://community.particle.io/u/wesner0019)\
**Post date:** [October 24, 2019, 5:07pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/9 "2019-10-24T17:07:01Z")

</div>

> [@peekay123](#):
>
> NULL terminated char array.

Is it best to use: (edit if looks like the 2nd option is used in particle code)

`char mode5[20] = {0};`

or

1. `char mode5[20];`
2. `memset(mode5, 0, sizeof(mode5));`

```auto
if (strcmp(mode5, "MODE_5_DISABLED") == 0 && millis() > 25000) {
   if (RESP_OK == Cellular.command("AT+UCGED=5\r\n")) {
       memset(mode5, 0, sizeof(mode5));
   }
}

```

---

<div class="post-metadata">

**Author:** ![ScruffR](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/scruffr/32/6952_2.png) [@ScruffR](https://community.particle.io/u/ScruffR)\
**Post date:** [October 24, 2019, 5:24pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/10 "2019-10-24T17:24:35Z")

</div>

You can use `strncmp()` to only compare the first n characters. No need to terminate (IIRC).

---

<div class="post-metadata">

**Author:** ![wesner0019](https://avatars.discourse-cdn.com/v4/letter/w/0ea827/32.png) [@wesner0019](https://community.particle.io/u/wesner0019)\
**Post date:** [October 24, 2019, 5:29pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/11 "2019-10-24T17:29:12Z")

</div>

> [@wesner0019](#):
>
> if (strcmp(mode5, "MODE\_5\_DISABLED") == 0 && millis() \> 25000) { if (RESP\_OK == Cellular.command("AT+UCGED=5\r\n")) { memset(mode5, 0, sizeof(mode5)); } }

@ScruffR

so this could work?

```auto
if (strncmp(mode5, "MODE_5_DISABLED", 6) == 0 && millis() > 25000) {
   if (RESP_OK == Cellular.command("AT+UCGED=5\r\n")) {
       memset(mode5, 0, sizeof(mode5));
   }
} 

```

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [October 24, 2019, 5:45pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/12 "2019-10-24T17:45:05Z")

</div>

@wesner0019, yes if you only want to compare the first 6 characters.

---

<div class="post-metadata">

**Author:** ![hwestbrook](https://avatars.discourse-cdn.com/v4/letter/h/5f9b8f/32.png) [@hwestbrook](https://community.particle.io/u/hwestbrook)\
**Post date:** [January 11, 2020, 1:10am UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/13 "2020-01-11T01:10:59Z")

</div>

@wesner0019,

Can I ask what you are trying to accomplish with this UCGED mode 5 command?

I’m curious, as I am also issuing this call to my Electron LTE’s in order to get an accurate cell signal level. I’m doing this because the Electron LTE RSSI and quality readings are not useful. Are you experiencing the same issue?

---

<div class="post-metadata">

**Author:** ![wesner0019](https://avatars.discourse-cdn.com/v4/letter/w/0ea827/32.png) [@wesner0019](https://community.particle.io/u/wesner0019)\
**Post date:** [January 16, 2020, 11:41pm UTC](https://community.particle.io/t/is-cellular-command-thread-safe/52860/14 "2020-01-16T23:41:56Z")

</div>

> [@wesner0019](#):
>
> UCGED

I was wanting to get the actual RSRP singnal value and also wnated to determine what band the device was on. Below is a callback I used

```auto
int callbackUCGED(int type, const char* buf, int len, char* response) {
  // buf format:+RSRP: 162,5110,"-075.00",
  sscanf(buf, "\r\n+RSRP: %*d,%d,\"%s\",\r\n", &earfcn, rsrp);
  sscanf(buf, "\r\n+UCGED: %s \r\n", mode5);
   if (earfcn >= 600 && earfcn <=1199) earfcn = 2; //1900Mhz
   else if (earfcn >= 1950 && earfcn <=2399) earfcn = 4; //1700Mhz
   else if (earfcn >= 5010 && earfcn <=5179) earfcn = 12; //700Mhz
   else if (earfcn == 65535) earfcn = 0; //not known or not detectable
  return WAIT;
}

```
