Skip to content

Instantly share code, notes, and snippets.

@CharlesOkwuagwu
Last active September 29, 2016 17:37
Show Gist options
  • Save CharlesOkwuagwu/d23cfd9f40a4be1f938ee2d145a72f67 to your computer and use it in GitHub Desktop.
Save CharlesOkwuagwu/d23cfd9f40a4be1f938ee2d145a72f67 to your computer and use it in GitHub Desktop.
sample data-proc for telegram
## Process Inbound Data
def handle_info({:tcp, _, data}, s) do
s = proc_raw(s.extra <> data, %{s | extra: ""})
:inet.setopts(s.socket, active: :once)
{:noreply, s}
end
defp proc_raw(raw, s) do
case raw do
<<0x7F, len::little-3*8, data::binary>> when byte_size(data) == len * 4 -> proc_data(data, s)
<<0x7F, len::little-3*8, data::binary>> when byte_size(data) > len * 4 -> proc_extra_data(data, len * 4, s)
<<0x7F, _::binary>> -> %{s | extra: raw}
<<len, data::binary>> when byte_size(data) == len * 4 -> proc_data(data, s)
<<len, data::binary>> when byte_size(data) > len * 4 -> proc_extra_data(data, len * 4, s)
<<_len, _::binary>> -> %{s | extra: raw}
end
end
defp proc_extra_data(raw, len, s) do
<<data::binary-size(len)-unit(8), extra::binary>> = raw
proc_raw(extra, proc_data(data, s))
end
defp proc_data(<<0::8*8, _msg_id::little-8*8, len::little-4*8, data::binary-size(len)-unit(8), _rm::binary>>, s) do
# log "#{s.tag}: << [#{TL.head(data)}] msg_id: #{msg_id} - [#{inspect self()}]"
process(data, 0, s)
end
defp proc_data(<<error_code::4*8-integer-signed-little>>, s) do
log "#{s.tag}-err: #{error_code}"
s
end
defp proc_data(<<auth_id::binary-size(8)-unit(8), msg_key::binary-size(16), enc_msg::binary>>, %MainLink.State{auth_id: auth_id} = s) do
{aes_key, aes_iv} = TL.Crypto.aes_key_iv(s.auth_key, msg_key, 8)
<<_hdr::binary-size(16), payload::binary>> = TL.Crypto.ige_dec(aes_key, aes_iv, enc_msg)
proc_msg_data(payload, s, 0)
end
defp proc_data(<<auth_id::binary-size(8)-unit(8), _::binary>>, s) do
log "#{s.tag}: INVALID AUTH-ID [#{Base.encode16(auth_id)}]\n"
%{s | extra: ""}
end
defp proc_msg_data(<<msg_id::little-8*8, seq_no::little-4*8, len::little-4*8, data::binary-size(len)-unit(8), pad::binary>>, %MainLink.State{content_count: content_count} = s, ix) when div(seq_no, 2) >= content_count do
proc_msg_data(msg_id, seq_no, len, data, pad, %{s | content_count: div(seq_no, 2)}, ix)
end
defp proc_msg_data(<<msg_id::little-8*8, seq_no::little-4*8, len::little-4*8, data::binary-size(len)-unit(8), pad::binary>>, s, ix) do
proc_msg_data(msg_id, seq_no, len, data, pad, s, ix)
end
defp proc_msg_data(data, s, _ix) do
log "#{s.tag}: ??? - #{Base.encode16(data)}"
s
end
defp proc_msg_data(msg_id, _seq_no, len, data, pad, s, ix) do
case data do
<<0x73F1F8DC::little-4*8, _count::little-4*8, msgs::binary>> ->
proc_msg_data(msgs, s, ix + 1)
<<body::binary-size(len)-unit(8)>> when byte_size(pad) < 16 ->
process(body, msg_id, s)
<<body::binary-size(len)-unit(8)>> ->
s = process(body, msg_id, s)
proc_msg_data(pad, s, ix + 1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment