Infinity loop in io.popen function in lua - lua

I want to execute following code infinitely.
However, if two devices are connected, the infinity loop is freeze at second scanning section(The second scanning section means that infinity loop begins second time and scan command is executed). Why this problem appears?
while true do
print("Hi")
s = io.popen("iw wlan0 scan")
s:close()
print("Done")
dis = io.popen("iw wlan0 disconnect")
dis:close()
c = io.popen("iw wlan0 connect Name")
c:close()
print("Goes to Scan")
end
Also, If I type commands in command line by hand(scan -> disconnect -> connect -> scan), then scan print result is repeat from 5 to 6 times automatically at second scanning. (When I execute scan command, the printed result is SYNC - End of SCAN, restore to 20MHz channel 32, Total BSS[02] bImprovedScan ............. Resume for bImprovedScan, SCAN_PENDING ............... and this printed text is repeat from 5 to 6 times). Is this situation is related to this problem?

I don't know what the iw command does, but using a pipe without reading anything from it and closing it immediately after opening it opens the possibility that the program never executes.
I suggest using os.execute instead of io.popen:
while true do
print("Hi")
os.execute("iw wlan0 scan; iw wlan0 disconnect; iw wlan0 connect Name")
print("Goes to Scan")
end

Related

Wireshark MATE: Calculate response time

I'm just trying to use MATE to calculate response time between each SMPP submit_sm and submit_sm_resp, this is the mate script I'm using:
Pdu smpp_pdu Proto smpp Transport mate {
Extract cmd From smpp.command_id;
Extract seq From smpp.sequence_number;
};
Gop smpp_session On smpp_pdu Match (seq) {
Start (cmd=4);
Stop (cmd=2147483652);
};
Done;
So basically, it exacts command id and sequence numbers, then in Gop uses command id for start/stop
4 = 0x00000004 = SUBMIT_SM
2147483652 = 0x80000004 = SUBMIT_SM_RESP
This should do the trick. But, now what?
I added a column with Delta Time Displayed, and this should show the response time for each submit_sm_resp, but this is not using MATE, just calculate the time between each previous packet:
How can I use MATE script?
If I use the following filter in a specific column:
mate.smpp_pdu.RelativeTime
I only got the seconds, for each packet, from starting trace:
As far I understood, MATE should setup time between START and STOP, but which is the filter I should use?
This doesn't shown anything:
mate.smpp_session.Time
Please advise,
Thank you,
Lucas
Find solution! I posted here just in case someone need it:
Because cmd is a string, the correct Gop will be:
Start (cmd="0x00000004");
Stop (cmd="0x80000004");
This will did the trick.

What exactly does `return` do in AutoHotKey?

In a comment chain, I ask:
Hmm, so the return doesn't play like a closing bracket like in other languages?
To which a user answers:
It's maybe easy to think of return as just something that stops the code execution from going further. #IfDirectives don't care about returns, or anything else related to code execution, because they have nothing to do with code execution. They are kind of just markers that enclose different parts of code within them
I have two questions from this:
If return is just something that stops code execution from going further, then how is it different to exit? They are both flow controls playing a role to determine The Top of the Script (the Auto-execute Section). I see that many people having this problem.
If return doesn't play like a closing bracket, then why does it appear in many places one expects a closing bracket? Especially when there is no subroutine involving in, like what is described in the formal definition. Take this example in Hotkeys:
#n::
Run Notepad
return
In AHK return is what you'd learn return to be from other programming languages. It's just that control flow, and in general the legacy syntax, in AHK is different from what you might be used to from other languages.
How is return different from exit?
If we're not trying to return a value from a function, and are just interested in the control flow, there is not much difference. But the difference is there.
You could indeed end an hotkey label with exit, and it would be the same as ending it with return.
From the documentation:
"If there is no caller to which to return, Return will do an Exit instead.".
I guess it's just convention to end hotkey labels with return.
So basically said, there is difference between the two, if return isn't about to do an exit.
Well when would this be?
For example:
MsgBox, 1
function()
MsgBox, 3
return ;this does an exit
function()
{
MsgBox, 2
return ;this does a return
}
The first return has no caller to which to return to, so it will do an exit.
The second return however does have a caller to return to do, so it will return there, and then execute the 3rd message box.
If we replaced the second return with an exit, the current thread would just be exited and the 3rd message box would never have been shown.
Here's the same exact example with legacy labels:
MsgBox, 1
gosub, label
MsgBox, 3
return ;this does an exit
label:
MsgBox, 2
return ;this does a return
I'm showing this, because they're very close to hotkey labels, and hotkey labels were something you were wondering a lot about.
In this specific example, if the line MsgBox, 3 didn't exist, replacing the second return with an exit would produce the same end result. But only because code execution is about to end anyway on the first return.
If return doesn't play like a closing bracket, then why does it appear in many places one expects a closing bracket?
In AHK v1, hotkeys and hotstrings work like labels, and labels are legacy. Labels don't care about { }s like modern functions do.
So we need something to stop the code execution. Return does that.
Consider the following example:
c::
MsgBox, % "Hotkey triggered!"
gosub, run_chrome
;code execution not ended
n::
MsgBox, % "Hotkey triggered!`nRunning notepad"
Run, notepad
;code execution not ended
run_chrome:
MsgBox, % "Running chrome"
run, chrome
WinWait, ahk_exe chrome.exe
WinMove, ahk_exe chrome.exe, , 500, 500
;code execution not ended
show_system_uptime:
MsgBox, % "System uptime: " A_TickCount " ms"
;code execution not ended
We're not ending code execution at any of the labels. Because of this, code execution will bleed into other parts of the code, in this case, into the other labels.
Try running the hotkeys and see how code execution bleeds into the other labels.
Because of this, the code execution needs to be ended somehow.
If using { } was supported by labels, it would indeed be the solution to keep the code execution where it needs to be.
And in fact AHK v2 hotkeys and hotstrings are no longer labels (they're only lookalikes). In v2 using { } is actually the correct way (the script wont even run if you don't use them).
See hotkeys from the AHK v2 documentation.
Another answer above already gave a good explanation.
So, to me:_
(return vs Exit is like gosub vs goto -- return (literal meaning) vs terminate. )
return completes (ends) the current subroutine, and returns from the current subroutine back to the calling subroutine;
Exit completes (ends) the current subroutine, and terminates (/exits /ends) the current thread (which discards all the previous calling subroutine);
where subroutines are inside a thread.
(subroutines are just like function calls or label calls (or hotkey label calls);
you can visualize this as if method calls (stack frame) in Java (, you can see this when you debug in an IDE))
Quotes:
[]
Return
Returns from a subroutine to which execution had previously jumped via function-call, Gosub, Hotkey activation, GroupActivate, or other means.
https://www.autohotkey.com/docs/commands/Return.htm
[]
Exit
Exits the current thread or (if the script is not persistent) the entire script.
https://www.autohotkey.com/docs/commands/Exit.htm
[]
Gosub
Jumps to the specified label and continues execution until Return is encountered.
https://www.autohotkey.com/docs/commands/Gosub.htm
[]
Goto
Jumps to the specified label and continues execution.
https://www.autohotkey.com/docs/commands/Goto.htm
[]
main difference is gosub comes back, and goto does not.
https://www.autohotkey.com/board/topic/46160-goto-vs-gosub/
[]
A subroutine and a function are essentially the same thing
Difference between subroutine , co-routine , function and thread?
[]
A subroutine is a portion of code which can be called to perform a specific task.
Execution of a subroutine begins at the target of a label and continues until a Return or Exit is encountered.
Since the end of a subroutine depends on flow of control,
any label can act as both a Goto target and the beginning of a subroutine.
https://www.autohotkey.com/docs/misc/Labels.htm#subroutines
[]
The current thread is defined as the flow of execution invoked by the most recent event;
examples include hotkeys, SetTimer subroutines, custom menu items, and GUI events.
The current thread can be executing commands within its own subroutine or within other subroutines called by that subroutine.
https://www.autohotkey.com/docs/misc/Threads.htm
(you may try out the following code to see the difference)
^r::
MsgBox, aaa
gosub, TestLabel
MsgBox, bbb
goto, TestLabel
MsgBox, ccc
return
TestLabel:
MsgBox, inside
return
; Exit
Return returns from a function (called with funcname(...) syntax) or subroutine (called with Gosub label). Subroutines/functions can call other subroutines/functions and so it's convenient to end them with Return rather than Exit. Exit ends the current thread of execution and won't transfer flow of control back to the caller.
For functions, Return also can return a value.
Return is not analogous to a closing bracket. Closing brackets can occur only at the end of a function and imply a Return but you can also Return anywhere in a function. It is common to return in an If statement to "bail out" of a function early, perhaps if some parameter had an invalid value.

Asterisk PBX - Infinite Loop when user disconnects while using 'Read' application from LUA

I'm configuring interactive dial plans for asterisk at the moment and because I already know some LUA I thought it'd be easier to go that route.
I have a start extension like this:
["h"] = function(c,e)
app.verbose("Hung Up")
end;
["s"] = function(c, e)
local d = 0
while d == 0 do
say:hello()
app.read("read_result", nil, 1)
d = channel["read_result"].value;
if d == 1 then
say:goodbye()
elseif d == 2 then
call:forward('front desk')
end
d = 0
end
say:goodbye()
end;
As you can see, I want to repeat the instructions say:hello() whenever
the user gives an invalid answer. However, if the user hangs up while
app.read waits for their answer, asterisk ends up in an infinite loop
since d will always be nil.
I WOULD check for d==nil to detect disconnection, but nil also shows
up when the user just presses the # pound sign during app.read.
So far I've taken to using for loops instead of while to limit the
maximum iterations that way, but I'd rather find out how to detect a disconnected
channel. I can't find any documentation on that though.
I also tried setting up a h extension, but the program won't go to it when the
user hangs up.
Asterisk Verbose Output:
[...]
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1") │ test.lua:3: in main chunk
-- Accepting a maximum of 1 digit. │ [C]: ?
-- User disconnected │root#cirro asterisk lua test.lua
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1") │Global B
-- Accepting a maximum of 1 digit. │LocalB-B->a
-- User disconnected │LocalB-A
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1") │LocalB-A
-- Accepting a maximum of 1 digit. │LocalB-A
-- User disconnected │root#cirro asterisk cp ~/test.call /var/spool/asterisk/outgoing
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1")
[...]
Thanks for any help you might be able to offer.
First of all you can see in app_read docs(and any other doc), that it return different values for incorrect execution(when channel is down).
Also this exact app offer simplified way of determine result:
core show application Read
-= Info about application 'Read' =-
[Synopsis]
Read a variable.
[Description]
Reads a #-terminated string of digits a certain number of times from the user
in to the given <variable>.
This application sets the following channel variable upon completion:
${READSTATUS}: This is the status of the read operation.
OK
ERROR
HANGUP
INTERRUPTED
SKIPPED
TIMEOUT
If that still not suite you, you can direct ask asterisk about CHANNEL(state)
PS You NEVER should write dialplan or any other program with infinite loop. Count your loops and exit at 10+. This will save ALOT of money for client.

DTrace build in built-in variable stackdepth always return 0

I am recently using DTrace to analyze my iOS app。
Everything goes well except when I try to use the built-in variable stackDepth。
I read the document here where shows the introduction of built-in variable stackDepth.
So I write some D code
pid$target:::entry
{
self->entry_times[probefunc] = timestamp;
}
pid$target:::return
{
printf ("-----------------------------------\n");
this->delta_time = timestamp - self->entry_times[probefunc];
printf ("%s\n", probefunc);
printf ("stackDepth %d\n", stackdepth);
printf ("%d---%d\n", this->delta_time, epid);
ustack();
printf ("-----------------------------------\n");
}
And run it with sudo dtrace -s temp.d -c ./simple.out。 unstack() function goes very well, but stackDepth always appears to 0。
I tried both on my iOS app and a simple C program.
So anybody knows what's going on?
And how to get stack depth when the probe fires?
You want to use ustackdepth -- the user-land stack depth.
The stackdepth variable refers to the kernel thread stack depth; the ustackdepth variable refers to the user-land thread stack depth. When the traced program is executing in user-land, stackdepth will (should!) always be 0.
ustackdepth is calculated using the same logic as is used to walk the user-land stack as with ustack() (just as stackdepth and stack() use similar logic for the kernel stack).
This seems like a bug in the Mac / iOS implementation of DTrace to me.
However, since you're already probing every function entry and return, you could just keep a new variable self->depth and do ++ in the :::entry probe and -- in the :::return probe. This doesn't work quite right if you run it against optimized code, because any tail-call-optimized functions may look like they enter but never return. To solve that, you can turn off optimizations.
Also, because what you're doing looks a lot like this, I thought maybe you would be interested in the -F option:
Coalesce trace output by identifying function entry and return.
Function entry probe reports are indented and their output is prefixed
with ->. Function return probe reports are unindented and their output
is prefixed with <-.
The normal script to use with -F is something like:
pid$target::some_function:entry { self->trace = 1 }
pid$target:::entry /self->trace/ {}
pid$target:::return /self->trace/ {}
pid$target::some_function:return { self->trace = 0 }
Where some_function is the function whose execution you want to be printed. The output shows a textual call graph for that execution:
-> some_function
-> another_function
-> malloc
<- malloc
<- another_function
-> yet_another_function
-> strcmp
<- strcmp
-> malloc
<- malloc
<- yet_another_function
<- some_function

nodemcu + esp8266 + hc-sr04 - tmr.now() difference is incorrect

i've started using nodemcu on esp8266.
I've connected esp with hc-sr04 (ultrasound sensor for distance measurement).
hc-sr04 need to receive high state for trig pin for 10us. After that hc send high state of echo pin. The time of the high state from echo pin can be different (depends of distance). The time is counted in us.
The problem is that this time from echo pin is incorrect (IMHO). I'm not sure but is this possible that tmr. from nodemcu is not as precise as it should? And why there is so big difference between times in each loop?
My code and below you will find time printings from code:
gpio.write(3,gpio.LOW)
gpio.mode(3,gpio.OUTPUT)
gpio.write(4,gpio.LOW)
gpio.mode(4,gpio.INT)
time=0
flag=0
i=1
function startDis(level)
time=tmr.now()
end
function endDis(level)
time=tmr.now()-time
flag=0
end
function trigger()
gpio.write(3,gpio.HIGH)
tmr.delay(10)
gpio.write(3,gpio.LOW)
flag=1
end
gpio.trig(4,'up',startDis)
gpio.trig(4,'down',endDis)
// ---------THIS PART HAS BEEN CHANGED--------
while i<10 do
if flag==0 then
trigger()
end
tmr.delay(1000000)
print(time)
i=i+1
end
//--------------- TO ------------
tmr.alarm(0,2000,1,function()
print(time)
print(i)
if flag==0 then
trigger()
end
i=i+1
if i==10 then tmr.stop(0) end
end)
Code prints:
0
440184038
1999856
442183990
4000221
444184055
6000175
446184287
7999686
Thanks for clues and solutions.
Petre, I'll do this as an answer because it doesn't fit into a quick comment. :(
You need to read some of the other discussion in the FAQ on how the overall SDK schedules tasks. You are assuming in your code that something like this happens:
<every 2mSec>
print(time)
print(i)
if flag==0 then
gpio.write(3,gpio.HIGH)
time=tmr.now()
tmr.delay(10)
gpio.write(3,gpio.LOW)
time=tmr.now()-time
flag=0
flag=1
end
i=i+1
if i==10 then tmr.stop(0) end
where in in reality what happens is closer to:
<every 2mSec task starts>
print(time)
print(i)
if flag==0 then
gpio.write(3,gpio.HIGH)
<H/W interupts calls low level GPIO which books up callback>
time=tmr.now()
tmr.delay(10)
<H/W interupts calls low level GPIO which books down callback>
gpio.write(3,gpio.LOW)
flag=1
end
i=i+1
if i==10 then tmr.stop(0) end
<task ends>
<possible TCP and other tasks run>
<up trigger is delivered>
time=tmr.now()
<task ends>
<possible TCP and other tasks run>
<down trigger is delivered>
time=tmr.now()-time
flag=0
<task ends>
The Esp8266 SDK is not a real Real Time O/S; it is event driven. It's your mindset that needs to get reorientated.
Using the tmr.delay() this way is the correct use, but you need HW test tools such as an oscilloscope or logic analyser to check what the actual delay is because you need to add in the time to process the Lua instructions.
Or even put the tmr.now() calls inline.
The real usecase for the trigger is where you have an input connected to a sensor such as a mechanical open/close detector and this avoids the need to poll it.

Resources