ejabberd_router:route error in ejabberd module - erlang

I am trying to create a simple echo bot in ejabberd. I cam get the mod_echo working ok and i'm fairly certain I had my own version working at one point (debugging has played tricks with my head). I am getting the error below but i can't figure out what to do next to debug it. There seems to be an issue routing but not quite sure why. Any tips?
2016-03-31 16:49:38.350 [debug] <0.448.0>#ejabberd_router:do_route:324 route
from {jid,<<"user1">>,<<"alchemy.local">>,<<"alchemy">>,<<"user1">>,<<"alchemy.local">>,<<"alchemy">>}
to {jid,<<>>,<<"echo.alchemy.local">>,<<>>,<<>>,<<"echo.alchemy.local">>,<<>>}
packet {xmlel,<<"message">>,[{<<"xml:lang">>,<<"en">>},{<<"to">>,<<"echo.alchemy.local">>},{<<"id">>,<<"aacca">>}],[{xmlcdata,<<"\n">>},{xmlel,<<"subject">>,[],[]},{xmlcdata,<<"\n">>},{xmlel,<<"body">>,[],[{xmlcdata,<<"testme">>}]},{xmlcdata,<<"\n">>},{xmlel,<<"nick">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/nick">>}],[{xmlcdata,<<"user1">>}]},{xmlcdata,<<"\n">>}]}
2016-03-31 16:49:38.351 [error] <0.448.0>#ejabberd_router:route:77 {function_clause,[{mod_echobot,route,[{jid,<<"user1">>,<<"alchemy.local">>,<<"alchemy">>,<<"user1">>,<<"alchemy.local">>,<<"alchemy">>},{jid,<<>>,<<"echo.alchemy.local">>,<<>>,<<>>,<<"echo.alchemy.local">>,<<>>},{xmlel,<<"message">>,[{<<"xml:lang">>,<<"en">>},{<<"to">>,<<"echo.alchemy.local">>},{<<"id">>,<<"aacca">>}],[{xmlcdata,<<"\n">>},{xmlel,<<"subject">>,[],[]},{xmlcdata,<<"\n">>},{xmlel,<<"body">>,[],[{xmlcdata,<<"testme">>}]},{xmlcdata,<<"\n">>},{xmlel,<<"nick">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/nick">>}],[{xmlcdata,<<"user1">>}]},{xmlcdata,<<"\n">>}]}],[{file,"mod_echobot.erl"},{line,86}]},{ejabberd_router,route,3,[{file,"src/ejabberd_router.erl"},{line,75}]},{ejabberd_c2s,check_privacy_route,5,[{file,"src/ejabberd_c2s.erl"},{line,2121}]},{ejabberd_c2s,session_established2,2,[{file,"src/ejabberd_c2s.erl"},{line,1288}]},{p1_fsm,handle_msg,10,[{file,"src/p1_fsm.erl"},{line,582}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}
when processing: {{jid,<<"user1">>,<<"alchemy.local">>,<<"alchemy">>,<<"user1">>,<<"alchemy.local">>,<<"alchemy">>},{jid,<<>>,<<"echo.alchemy.local">>,<<>>,<<>>,<<"echo.alchemy.local">>,<<>>},{xmlel,<<"message">>,[{<<"xml:lang">>,<<"en">>},{<<"to">>,<<"echo.alchemy.local">>},{<<"id">>,<<"aacca">>}],[{xmlcdata,<<"\n">>},{xmlel,<<"subject">>,[],[]},{xmlcdata,<<"\n">>},{xmlel,<<"body">>,[],[{xmlcdata,<<"testme">>}]},{xmlcdata,<<"\n">>},{xmlel,<<"nick">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/nick">>}],[{xmlcdata,<<"user1">>}]},{xmlcdata,<<"\n">>}]}}
2016-03-31 16:50:16.356 [debug] <0.447.0>#ejabberd_receiver:process_data:282 Received XML on stream = <<"\n">>

It seems that in the code sample (which was from an older sample i found online) https://gist.github.com/stevenlivz/d666200595a23c42b2a662fef87bf281 i need to use <<"message">> in the clauses to actually match, whereas the sample code i used did not do that, using just "message" and so on. Also, also worth noting that xmlelement is now xmlel and so clauses also need to be updated. E.g.
route(From, To, {xmlel, <<"message">>, _, _} = Packet) ->

Related

Unable to read from Agilent 53131A by GPIB in the simple way

Hi I am using LabView 2012, Delphi XE7 and GPIB (I think 488.2), Win7 SP1 and Agilent 53131A.
I used the given NI examples.
NI Labview example - Found in LabVIEW's help - GPIB.vi.
I tried writing and reading to query frequencies from 2 channels and they are successful.
They are are sent and read in succession.
*IDN?
:FUNC 'FREQ 1'
:READ:FREQ?
If they are successful, that meant GPIB for Agilent and NI MAX and driver are successfully installed and configured.
I am also able to use KeySight Connection Expert's to write and read, Again it is also successful.
However, When I used the given NI example in Delphi. Orginally it was saved as Delphi 3 or 4.
I used the Scope Simple example for universal counter. I used it mostly for writing and reading in the simple way. All it needs initialization, read/write and cleanup
I changed the following codes as shown below, in SimpleForm.pas
The detected device is at GPIB0::3::INSTR so, at line 32,
PRIMARY_ADDR_OF_COUNTER = 3;
String to write and read so, at line 132,
CommandBox.Text := '*IDN?';
then it was compiled with no error and run.
String to write was successfully
But upon reading, it was not successfully.
The string output is supposed to be ' HEWLETT-PACKARD,53131A,0,4806'.
The error at the end of the program is as follows below:-
Unable to read from device
ibsta = SC000 <ERR TMO>
iberr = 6 <EABO>
ibcntl = 0
From these readings, I figured out as :-
EABO means abort
I am not familiar with working of GPIB. Kindly advise.
You are correct that EABO is the identifier for an abort. In addition, we can see from ibsta = SC000 <ERR TMO> that the cause of the abort was a GPIB timeout error. I am not familiar with Keysight Connection Expert or your instrument, but since the error was from GPIB timeout, the most likely causes are:
The query was improperly formatted and the instrument thought it was just a write statement with no response needed. (That's probably why the write function had no error, but the read function timed out.)
The query was improperly formatted and the instrument returned an error.
Instrument needs to have 'Talker' capability enabled to send data. (Most instruments do this automatically with queries.)
For more information on generic GPIB commands, see this reference from the folks at National Instruments.

Use stderr in lua io.popen to determine faulty function call

I'm making a function that can read the metadata of the current song playing in spotify. This is being programmed in lua since it is an implementation for awesome wm. I got the following line to get all the metadata that I can later use.
handle = io.popen('qdbus org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Metadata | awk -F: \'{$1=\"\";$2=\"\";print substr($0,4)}\'')
However when Spotify is not running I don't get the expected information and qdbus writes an error to the stderr stream. I wanted to use the fact that qdbus writes to the error stream to determine a fault and stop the program there. (This should also catch any other errors not related to wheter spotify is running or not)
My understanding is that lua popen uses popen3 that can subdivide between stdout and stderr. but all my efforts so far are fruitless and my error stream is always empty. Is it possible to check for a non nil value in the stderr in order to determine a faulty call to qdbus (or awk)?
thanks!
I think you can redirect stderr to stdout in the call to popen like this:
handle = io.popen("somecommand 2>&1")
If you want to differentiate stderr and stdout, you cannot do it with the io library but you can with luaposix. See this answer for instance.
You can checkout juci.exec which I wrote for JUCI webgui. I struggled with the same problem and I ended up using luaposix for this kind of thing when I really need two separate streams. My implementation also gives you the program exit code which is good for testing for errors: https://github.com/mkschreder/juci/blob/master/juci/lua/core.lua

Riak Erlang map/reduce returns {error,notfound}

I've running the following Riak map phase:
-module(delete_map_function).
-export([get_keys/3]).
%Returns bucket and key pairs from a map phase
get_keys(Value,_Keydata,_Arg) ->
[[riak_object:bucket(Value),riak_object:key(Value)]].
And the following Riak reduce phase: http://contrib.basho.com/delete_keys.html
I keep getting this error message:
{"phase":0,"error":"function_clause","input":"{{error,notfound},{<<\"my_bucket\">>,<<\"item_key\">>},undefined}","type":"error","stack":"[{riak_object,bucket,[{error,notfound}],[{file,\"src/riak_object.erl\"},{line,251}]},{delete_map_function,get_keys,3,[{file,\"delete_map_function.erl\"},{line,7}]},{riak_kv_mrc_map,map,3,[{file,\"src/riak_kv_mrc_map.erl\"},{line,164}]},{riak_kv_mrc_map,process,3,[{file,\"src/riak_kv_mrc_map.erl\"},{line,140}]},{riak_pipe_vnode_worker,process_input,3,[{file,\"src/riak_pipe_vnode_worker.erl\"},{line,444}]},{riak_pipe_vnode_worker,wait_for_input,2,[{file,\"src/riak_pipe_vnode_worker.erl\"},{line,376}]},{gen_fsm,...},...]"}
I'm running the job via Java:
MapReduceResult mapReduceResult = RiakUtils.getPBClient().mapReduce(iq)
.addMapPhase(new NamedErlangFunction("delete_map_function", "get_keys"))
.addReducePhase(new NamedErlangFunction("delete_reduce_function", "delete"))
.execute();
I've read somewhere that I should use the filter_notfound argument in the Map phase, but I still keep getting the error even after adding it:
MapReduceResult mapReduceResult = RiakUtils.getPBClient().mapReduce(iq)
.addMapPhase(new NamedErlangFunction("delete_map_function", "get_keys"), "filter_notfound")
.addReducePhase(new NamedErlangFunction("delete_reduce_function", "delete"))
.execute();
I'm running Riak 1.3 and using the Riak Java client v1.1.0
First. I think it is not efficient way to delete keys via map/reduce phases. if you got keys list and feed it to map phase riak will first read all objects and then give it to your functions. So if you only need to delete object, better do it without read.
Second. All your map/reduce functions should be written with following exceptions:
instead of Value, you can get {error, notfound} because of eventual nature of riak.
also you can get deleted riak object as Value. You can know that object was deleted by special flag dict:is_key(<<"X-Riak-Deleted">>, riak_object:get_metadata(RiakObj)):
Third. To fix your error you should filter notfound keys from the list:
get_keys({error, notfound},_Keydata,_Arg) ->
[];
get_keys(Value,_Keydata,_Arg) ->
[[riak_object:bucket(Value),riak_object:key(Value)]].

Erlang Bit Syntax pattern matching works in shell but not as passed argument

I am trying to make a simple UDP packet decoder.
packet_decoder(Packet)->
<<Opts:8,MobIdLength:8,MobId:64,MobIdType:8,MgeType:8,SeqNum:16,Rest/binary>> = Packet,
io:format("Options:~p~n",Opts),
io:format("MobIdLength:~p~n",MobIdLength),
io:format("MobId:~p~n",MobId),
io:format("MobIdType:~p~n",MobIdType),
io:format("MgeType:~p~n",MgeType),
io:format("SeqNum:~p~n",SeqNum).
Packet is passed by a receive loop:
rcv_loop(Socket) ->
inet:setopts(Socket, [{active, once}, binary]),
io:format("rcvr started:~n"),
receive
{udp, Socket, Host, Port, Bin} ->
packet_decoder(Bin),
rcv_loop(Socket)
end.
I keep getting(following error edited 9/7/12 9:30 EST):
** exception error: no match of right hand side value
<<131,8,53,134,150,4,149,0,80,15,1,2,1,2,0,16,80,71,115,
52,80,71,115,53,24,63,227,197,211,...>>
in function udp_server:packet_decoder/1
called as udp_server:packet_decoder(<<131,8,53,134,150,4,149,0,80,15,
1,2,1,2,0,16,80,71,115,52,80,71,
115,53,24,63,227,197,...>>)
in call from udp_server:rcv_loop/1
in call from udp_server:init/0
If I create the same variable in the Erlang shell as a binary, i.e.
Packet = <<131,8,53,134,150,4,149,0,80,15,1,2,1,2,0,16,80,71,115,52,80,71,115,53,24,63,227,197,211,228,89,72,0,0,0,0,0,0,0,16,0,5,5,32,1,4,255,159,15,18,28,0,34,62,2,0,0,0,0,0,0,0,47,67>>.
<<Opts:8,MobIdLength:8,MobId:64,MobIdType:8,MgeType:8,SeqNum:16,Rest/binary>> = Packet.
It works just fine. Is there some subtlety in passing this to a function that I am missing? I have tried what I think is everything(except the right way). I tried setting the type and size. I also just tried
<<Rest/binary>> = Packet.
To no avail. Any help much appreciated.
The error you are getting when you run your code does not match your code. The error you are getting:
** exception error: no match of right hand side value ...
is a badmatch error and comes from an explicit = match where the pattern does not match the value from the RHS. There is no = in the code for rcv_loop/1. This implies that the loop you are running is not this code. So there are some questions to be asked:
When you have recompiled the module containing rcv_loop/1 have you restarted the loop so you run the new code? This is not done automagically.
Are you sure you are loading/running the code you think you are? I know this question sounds stupid but it is very easy, and not uncommon, to work on one version of the code and load another. You need to get the paths right.
The other things about mentioned about your code would not give this error. The calls to io:format/2 are wrong but would result in errors when you make the actual calls to io:format/2. Using the variable Socket as you do is not an error, it just means that you only want to receive UDP packets from just that socket.
EDIT : the first part of my answer was completely wrong so in order to not mislead, I deleted it.
Like spotted Alexey Kachayev io:format takes as second parameter a list, so :
packet_decoder(Packet)->
<<Opts:8,MobIdLength:8,MobId:64,MobIdType:8,MgeType:8,SeqNum:16,Rest/binary>> = Packet,
io:format("Options:~p~n",[Opts]),
io:format("MobIdLength:~p~n",[MobIdLength]),
io:format("MobId:~p~n",[MobId]),
io:format("MobIdType:~p~n",[MobIdType]),
io:format("MgeType:~p~n",[MgeType]),
io:format("SeqNum:~p~n",[SeqNum]).
I figured it out(kinda). I had been working on this in erlide in eclipse which had worked fine for all of the other parts of the. I tried compiling it from the erl shell and it worked fine. There must be some minor difference in the way eclipse is representing the source or the way it invokes the erlang compiler and shell. I will take it up with erlide.org. Thanks for the help!

Two quick consecutive calls to wf:insert_bottom end up in the reverse order

Using Nitrogen, the Erlang web framework, I have the following method that receives messages and adds them to the bottom of an html element:
receive_messages() ->
receive
Message ->
io:format("~p received ~p", [self(), Message]),
wf:insert_bottom(messages, [#p{}, #span { text=io_lib:format("~p", [Message]) }])
end,
wf:comet_flush(),
receive_messages().
It is set as the usual way for comet:
wf:comet(fun() -> receive_messages() end)
It receives two messages very quickly:
<0.907.0> received {starting_chat,<0.905.0>}
<0.907.0> received {connected_to,<0.902.0>}
This is what I see in the HTML:
{connected_to, <0.902.0>}
{starting_chat, <0.905.0>}
Somehow, they ended in the reverse order.
I've started adding timer:sleep() calls to this method. With 50 milliseconds, they are in the correct order, with 20 they are not. When they are in the incorrect order they seem to be always in the incorrect order, it seems very deterministic.
Any ideas why? Is this a bug? Any ideas what should I do to get them in the correct order other than sleeping?
Also asked on the mailing list, in case there's more info there.
wf_comet.erl has a "strange" reverse call after applying inner_collect_content. My guess is that inner_collect_content used to be tail-recursive sometime ago.
If you apply the timeout, your messages are collected in different loops, one-by-one, so the order is not reversed anymore.
There seems to be a commit fixing this on another repository:
http://github.com/gersh/nitrogen/commit/a8bfcb23d003e68f7394a0455285beeb0fbf9b09

Resources