2017-10-12 09:50:17 +08:00
|
|
|
--[[
|
|
|
|
Local netcard wrapper
|
|
|
|
This require should return a table like:
|
|
|
|
{
|
|
|
|
broadcast=function(port,...):bool
|
|
|
|
send=function(uuid,port,...):bool
|
|
|
|
open=function(port):bool
|
|
|
|
isOpen=function(port):bool
|
|
|
|
close=function(port):bool
|
|
|
|
}
|
|
|
|
--]]
|
|
|
|
local netcard=require("localNetcard")
|
|
|
|
|
|
|
|
-- Check Netcard
|
|
|
|
if(netcard.broadcast==nil or
|
|
|
|
netcard.send==nil or
|
|
|
|
netcard.open==nil or
|
|
|
|
netcard.isOpen==nil or
|
|
|
|
netcard.close==nil) then
|
|
|
|
print("Error: netcard invalid.")
|
|
|
|
end
|
2017-10-11 22:20:32 +08:00
|
|
|
|
2017-10-12 09:50:17 +08:00
|
|
|
local sker= -- Socket Kernel Table
|
|
|
|
{
|
|
|
|
fdset= -- Store information of sockets
|
|
|
|
{
|
|
|
|
--[[
|
|
|
|
status : string ="Ready" "Connected" "Closed"
|
|
|
|
remote_hwport : int
|
|
|
|
remote_cookie : string
|
|
|
|
--]]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
local arpker={} -- ARP Kernel Table
|
|
|
|
|
|
|
|
|
|
|
|
function _findFirstAvaliableSocket()
|
|
|
|
local i=0
|
|
|
|
while ( sker.fdset[i] ~= nil ) do i=i+1 end
|
|
|
|
return i
|
2017-10-11 22:20:32 +08:00
|
|
|
end
|
|
|
|
|
2017-10-12 09:50:17 +08:00
|
|
|
function _doCreateSocket(sfd)
|
|
|
|
if(sker.fdset[sfd]~=nil) then return false,"sfd invalid"
|
|
|
|
else
|
|
|
|
sker.fdset[sfd]=
|
|
|
|
{
|
|
|
|
status="Ready"
|
|
|
|
}
|
|
|
|
return true,"Success"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function _getSocketStatus(sfd)
|
|
|
|
if(sker.fdset[sfd]==nil) then return nil
|
|
|
|
else
|
|
|
|
return sker.fdset[sfd].status
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function _setSocketStatus(sfd,status,...)
|
|
|
|
if(sker.fdset[sfd]==nil) then return false
|
|
|
|
else
|
|
|
|
sker.fdset[sfd].status=status
|
|
|
|
if(status=="Connected") then
|
|
|
|
sker.fdset[sfd].remote_hwport=arg[1]
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function _isPortValid(port)
|
|
|
|
return port>0 and port<65536
|
|
|
|
end
|
|
|
|
|
|
|
|
function _doConnect(sfd,remote_uuid,port) -- Connect to a remote device via uuid and port
|
|
|
|
-- Send SYN package (1,1,1)
|
|
|
|
local syn=string.pack("iii",1,1,1)
|
|
|
|
if(not netcard.send(remote_uuid,port,syn)) then
|
|
|
|
return -1,"Network error"
|
|
|
|
end
|
|
|
|
-- Wait 1.5 seconds for SYN+ACK (1,1,3)
|
|
|
|
local e,remote_hwport=event.pull(1.5,"net_synack")
|
|
|
|
if(e==nil) then
|
|
|
|
return -2,"Connection timed out"
|
|
|
|
end
|
|
|
|
--- Send ACK package (1,1,2)
|
|
|
|
local ack=string.pack("iii",1,1,2)
|
|
|
|
if(not netcard.send(remote_uuid,port,ack)) then
|
|
|
|
return -1,"Network error"
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Connection established
|
|
|
|
return 0,"Success",remote_hwport
|
|
|
|
end
|
|
|
|
|
|
|
|
function _isInArpCache(tag) -- Check ARP Check Table with tag for uuid
|
|
|
|
if(arpker[tag]~=nil) then
|
|
|
|
return true,arpker[tag].uuid
|
|
|
|
else
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function _generateARPQuest(tag) -- Generate a ARP quest
|
|
|
|
local s=string.pack("iiii",1,0,1,string.length(tag))
|
|
|
|
s=s..tag
|
|
|
|
return s
|
|
|
|
end
|
2017-10-11 22:20:32 +08:00
|
|
|
|
2017-10-12 09:50:17 +08:00
|
|
|
function _doArpBroadcastQuery(tag) -- Broadcast ARP quest to hardware port 9 (arp)
|
|
|
|
if(netcard.broadcast(9,tag)) then return true,"Success"
|
|
|
|
else return false,"Netcard error"
|
|
|
|
end
|
|
|
|
|
|
|
|
function socket() -- Allocate a new socket
|
|
|
|
local idx=_findFirstAvaliableSocket()
|
|
|
|
local ret,emsg=_doCreateSocket(idx)
|
|
|
|
if(not ret) then
|
|
|
|
return -1,emsg
|
|
|
|
else
|
|
|
|
return ret,emsg
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function connect(sfd,remote_tag,port) -- Connect to a remote device
|
|
|
|
if(_getSocketStatus(sfd)~="Ready") then
|
|
|
|
return -1,"Socket not ready"
|
|
|
|
elseif(not _isPortValid(port)) then
|
|
|
|
return -2,"Port Invalid"
|
|
|
|
else
|
|
|
|
-- Try to resolve remote_tag to remote_uuid
|
|
|
|
local remote_uuid=do_arp_query(remote_tag)
|
|
|
|
if(remote_uuid == nil) then
|
|
|
|
return -3,"Tag can not be resolved into uuid"
|
|
|
|
else
|
|
|
|
local eret,emsg,remote_hwport=_doConnect(sfd,remote_uuid,port)
|
|
|
|
if(eret==0) then
|
|
|
|
_setSocketStatus(sfd,"Connected",remote_hwport)
|
|
|
|
return 0,"Success"
|
|
|
|
else
|
|
|
|
return eret,emsg
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-10-11 22:20:32 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
function bind(sfd,port) -- Bind socket at specific port
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function listen(sfd,sz) -- Set size of queue for waiting connections
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function accept(sfd) -- Accept Connection
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function send(sfd,...) -- Standard Network I/O
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function recv(sfd) -- Standard Network I/O
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function shutdown(sfd) -- Close Socket
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function close(sfd) -- Close Socket
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function do_dhcp_client() -- Connect to DHCP Server and try to get a tag.
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function do_arp_broadcast() -- ARP: Broadcast tag and uuid information of this device
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function arp_listener() -- ARP: Listen to arp broadcast and record informations. Notice that this listener also replies to specific arp-request
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-10-12 09:50:17 +08:00
|
|
|
function do_arp_query(tag) -- ARP: Query uuid with tag, might send arp-request
|
|
|
|
local ret,uuid=_isInArpCache(tag)
|
|
|
|
if(ret) then return uuid
|
|
|
|
else
|
|
|
|
local quest=_generateARPQuest(tag)
|
|
|
|
for i=1,3,1 do
|
|
|
|
if(_doArpBroadcastQuery(quest)) then
|
|
|
|
local e,etag,euuid=event.pull(0.5,"net_newarp")
|
|
|
|
if(e~=nil) then return euuid end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return nil -- Failed to query arp in 3 tries.
|
|
|
|
end
|
2017-10-11 22:20:32 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
function run_arp() -- Start ARP Services in background
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function run_dhcp_client() -- Start DHCP Client in background
|
|
|
|
|
2017-10-12 09:50:17 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
function run_tcp() -- Start TCP Services in background
|
|
|
|
|
2017-10-11 22:20:32 +08:00
|
|
|
end
|