So I am trying to get into using the python library Quarry, but I have had problems with the proxy which is the feature I am trying to use. When I am using the default "proxy_hide_chat.py" example, when I try to load the server in the server list on mc version 1.19.3 it gives this error
No name known for packet: (761, 'status', 'upstream', 0)
Traceback (most recent call last):
File "/home/todd/.local/lib/python3.10/site-packages/quarry/net/protocol.py", line 205, in get_packet_name
return packets.packet_names[key]
KeyError: (761, 'status', 'upstream', 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/todd/.local/lib/python3.10/site-packages/quarry/net/protocol.py", line 241, in data_received
name = self.get_packet_name(buff.unpack_varint())
File "/home/todd/.local/lib/python3.10/site-packages/quarry/net/protocol.py", line 207, in get_packet_name
raise ProtocolError("No name known for packet: %s" % (key,))
quarry.net.protocol.ProtocolError: No name known for packet: (761, 'status', 'upstream', 0)
^C[todd#todd minecraftProxy]$ python teleport_proxy.py
Traceback (most recent call last):
File "/home/todd/.local/lib/python3.10/site-packages/twisted/internet/tcp.py", line 1334, in startListening
skt.bind(addr)
OSError: [Errno 98] Address already in use
When I try and connect to the server I get the error "Unknown protocol version" in minecraft.
I have tried to set the protocol version to 761 using this:
factory.protocol_version=761
but it doesn't do anything.
EDIT:
Here is the code:
"""
"Quiet mode" example proxy
Allows a client to turn on "quiet mode" which hides chat messages
This client doesn't handle system messages, and assumes none of them contain chat messages
"""
from twisted.internet import reactor
from quarry.types.uuid import UUID
from quarry.net.proxy import DownstreamFactory, Bridge
class QuietBridge(Bridge):
quiet_mode = False
def packet_upstream_chat_command(self, buff):
command = buff.unpack_string()
if command == "quiet":
self.toggle_quiet_mode()
buff.discard()
else:
buff.restore()
self.upstream.send_packet("chat_command", buff.read())
def packet_upstream_chat_message(self, buff):
buff.save()
chat_message = self.read_chat(buff, "upstream")
self.logger.info(" >> %s" % chat_message)
if chat_message.startswith("/quiet"):
self.toggle_quiet_mode()
elif self.quiet_mode and not chat_message.startswith("/"):
# Don't let the player send chat messages in quiet mode
msg = "Can't send messages while in quiet mode"
self.send_system(msg)
else:
# Pass to upstream
buff.restore()
self.upstream.send_packet("chat_message", buff.read())
def toggle_quiet_mode(self):
# Switch mode
self.quiet_mode = not self.quiet_mode
action = self.quiet_mode and "enabled" or "disabled"
msg = "Quiet mode %s" % action
self.send_system(msg)
def packet_downstream_chat_message(self, buff):
chat_message = self.read_chat(buff, "downstream")
self.logger.info(" :: %s" % chat_message)
# All chat messages on 1.19+ are from players and should be ignored in quiet mode
if self.quiet_mode and self.downstream.protocol_version >= 759:
return
# Ignore message that look like chat when in quiet mode
if chat_message is not None and self.quiet_mode and chat_message.startswith("<"):
return
# Pass to downstream
buff.restore()
self.downstream.send_packet("chat_message", buff.read())
def read_chat(self, buff, direction):
buff.save()
if direction == "upstream":
p_text = buff.unpack_string()
buff.discard()
return p_text
elif direction == "downstream":
# 1.19.1+
if self.downstream.protocol_version >= 760:
p_signed_message = buff.unpack_signed_message()
buff.unpack_varint() # Filter result
p_position = buff.unpack_varint()
p_sender_name = buff.unpack_chat()
buff.discard()
if p_position not in (1, 2): # Ignore system and game info messages
# Sender name is sent separately to the message text
return ":: <%s> %s" % (
p_sender_name, p_signed_message.unsigned_content or p_signed_message.body.message)
return
p_text = buff.unpack_chat().to_string()
# 1.19+
if self.downstream.protocol_version == 759:
p_unsigned_text = buff.unpack_optional(lambda: buff.unpack_chat().to_string())
p_position = buff.unpack_varint()
buff.unpack_uuid() # Sender UUID
p_sender_name = buff.unpack_chat()
buff.discard()
if p_position not in (1, 2): # Ignore system and game info messages
# Sender name is sent separately to the message text
return "<%s> %s" % (p_sender_name, p_unsigned_text or p_text)
elif self.downstream.protocol_version >= 47: # 1.8.x+
p_position = buff.unpack('B')
buff.discard()
if p_position not in (1, 2) and p_text.strip(): # Ignore system and game info messages
return p_text
else:
return p_text
def send_system(self, message):
if self.downstream.protocol_version >= 760: # 1.19.1+
self.downstream.send_packet("system_message",
self.downstream.buff_type.pack_chat(message),
self.downstream.buff_type.pack('?', False)) # Overlay false to put in chat
elif self.downstream.protocol_version == 759: # 1.19
self.downstream.send_packet("system_message",
self.downstream.buff_type.pack_chat(message),
self.downstream.buff_type.pack_varint(1)) # Type 1 for system chat message
else:
self.downstream.send_packet("chat_message",
self.downstream.buff_type.pack_chat(message),
self.downstream.buff_type.pack('B', 0),
self.downstream.buff_type.pack_uuid(UUID(int=0)))
class QuietDownstreamFactory(DownstreamFactory):
bridge_class = QuietBridge
motd = "Proxy Server"
def main(argv):
# Parse options
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--listen-host", default="0.0.0.0", help="address to listen on")
parser.add_argument("-p", "--listen-port", default=12345, type=int, help="port to listen on")
parser.add_argument("-b", "--connect-host", default="127.0.0.1", help="address to connect to")
parser.add_argument("-q", "--connect-port", default=25565, type=int, help="port to connect to")
args = parser.parse_args(argv)
# Create factory
factory = QuietDownstreamFactory()
factory.connect_host = args.connect_host
factory.connect_port = args.connect_port
# Listen
factory.protocol_version=761
factory.listen(args.listen_host, args.listen_port)
reactor.run()
if __name__ == "__main__":
import sys
main(sys.argv[1:])
Try agan the fctory protocol (for minecraft 1.19) 759
Related
Trying to use the IntradayTickExample code enclosed below. However I kept getting the following message. It says about authorization so I guess its getting stuck in the main. But I have no idea why this wouldn't work as its a BBG example?
My thoughts:
- It exits with code 0 so everything works well.
- It seems to go debug through the code until the authorisation section
- I cant find any way to change anything else r./e. the authorisation
C:\Users\ME\MyNewEnv\Scripts\python.exe F:/ME/BloombergWindowsSDK/Python/v3.12.2/examples/IntradayTickExample.py
IntradayTickExample
Connecting to localhost:8194
TokenGenerationFailure = {
reason = {
source = "apitkns (apiauth) on ebbdbp-ob-596"
category = "NO_AUTH"
errorCode = 12
description = "User not in emrs userid=DBG\ME firm=8787"
subcategory = "INVALID_USER"
}
}
Failed to get token
No authorization
Process finished with exit code 0
And full code below
# IntradayTickExample.py
from __future__ import print_function
from __future__ import absolute_import
import blpapi
import copy
import datetime
from optparse import OptionParser, Option, OptionValueError
TICK_DATA = blpapi.Name("tickData")
COND_CODE = blpapi.Name("conditionCodes")
TICK_SIZE = blpapi.Name("size")
TIME = blpapi.Name("time")
TYPE = blpapi.Name("type")
VALUE = blpapi.Name("value")
RESPONSE_ERROR = blpapi.Name("responseError")
CATEGORY = blpapi.Name("category")
MESSAGE = blpapi.Name("message")
SESSION_TERMINATED = blpapi.Name("SessionTerminated")
TOKEN_SUCCESS = blpapi.Name("TokenGenerationSuccess")
TOKEN_FAILURE = blpapi.Name("TokenGenerationFailure")
AUTHORIZATION_SUCCESS = blpapi.Name("AuthorizationSuccess")
TOKEN = blpapi.Name("token")
def authOptionCallback(option, opt, value, parser):
vals = value.split('=', 1)
if value == "user":
parser.values.auth = "AuthenticationType=OS_LOGON"
elif value == "none":
parser.values.auth = None
elif vals[0] == "app" and len(vals) == 2:
parser.values.auth = "AuthenticationMode=APPLICATION_ONLY;"\
"ApplicationAuthenticationType=APPNAME_AND_KEY;"\
"ApplicationName=" + vals[1]
elif vals[0] == "userapp" and len(vals) == 2:
parser.values.auth = "AuthenticationMode=USER_AND_APPLICATION;"\
"AuthenticationType=OS_LOGON;"\
"ApplicationAuthenticationType=APPNAME_AND_KEY;"\
"ApplicationName=" + vals[1]
elif vals[0] == "dir" and len(vals) == 2:
parser.values.auth = "AuthenticationType=DIRECTORY_SERVICE;"\
"DirSvcPropertyName=" + vals[1]
else:
raise OptionValueError("Invalid auth option '%s'" % value)
def checkDateTime(option, opt, value):
try:
return datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
except ValueError as ex:
raise OptionValueError(
"option {0}: invalid datetime value: {1} ({2})".format(
opt, value, ex))
class ExampleOption(Option):
TYPES = Option.TYPES + ("datetime",)
TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
TYPE_CHECKER["datetime"] = checkDateTime
def parseCmdLine():
parser = OptionParser(description="Retrieve intraday rawticks.",
epilog="Notes: " +
"1) All times are in GMT. " +
"2) Only one security can be specified.",
option_class=ExampleOption)
parser.add_option("-a",
"--ip",
dest="host",
help="server name or IP (default: %default)",
metavar="ipAddress",
default="localhost")
parser.add_option("-p",
dest="port",
type="int",
help="server port (default: %default)",
metavar="tcpPort",
default=8194)
parser.add_option("-s",
dest="security",
help="security (default: %default)",
metavar="security",
default="IBM US Equity")
parser.add_option("-e",
dest="events",
help="events (default: TRADE)",
metavar="event",
action="append",
default=[])
parser.add_option("--sd",
dest="startDateTime",
type="datetime",
help="start date/time (default: %default)",
metavar="startDateTime",
default=None)
parser.add_option("--ed",
dest="endDateTime",
type="datetime",
help="end date/time (default: %default)",
metavar="endDateTime",
default=None)
parser.add_option("--cc",
dest="conditionCodes",
help="include condition codes",
action="store_true",
default=False)
parser.add_option("--auth",
dest="auth",
help="authentication option: "
"user|none|app=<app>|userapp=<app>|dir=<property>"
" (default: %default)",
metavar="option",
action="callback",
callback=authOptionCallback,
type="string",
default="user")
(options, args) = parser.parse_args()
if not options.host:
options.host = ["localhost"]
if not options.events:
options.events = ["TRADE"]
return options
def authorize(authService, identity, session, cid):
tokenEventQueue = blpapi.EventQueue()
session.generateToken(eventQueue=tokenEventQueue)
# Process related response
ev = tokenEventQueue.nextEvent()
token = None
if ev.eventType() == blpapi.Event.TOKEN_STATUS or \
ev.eventType() == blpapi.Event.REQUEST_STATUS:
for msg in ev:
print(msg)
if msg.messageType() == TOKEN_SUCCESS:
token = msg.getElementAsString(TOKEN)
elif msg.messageType() == TOKEN_FAILURE:
break
if not token:
print("Failed to get token")
return False
# Create and fill the authorization request
authRequest = authService.createAuthorizationRequest()
authRequest.set(TOKEN, token)
# Send authorization request to "fill" the Identity
session.sendAuthorizationRequest(authRequest, identity, cid)
# Process related responses
startTime = datetime.datetime.today()
WAIT_TIME_SECONDS = 10
while True:
event = session.nextEvent(WAIT_TIME_SECONDS * 1000)
if event.eventType() == blpapi.Event.RESPONSE or \
event.eventType() == blpapi.Event.REQUEST_STATUS or \
event.eventType() == blpapi.Event.PARTIAL_RESPONSE:
for msg in event:
print(msg)
if msg.messageType() == AUTHORIZATION_SUCCESS:
return True
print("Authorization failed")
return False
endTime = datetime.datetime.today()
if endTime - startTime > datetime.timedelta(seconds=WAIT_TIME_SECONDS):
return False
def printErrorInfo(leadingStr, errorInfo):
print("%s%s (%s)" % (leadingStr, errorInfo.getElementAsString(CATEGORY),
errorInfo.getElementAsString(MESSAGE)))
def processMessage(msg):
data = msg.getElement(TICK_DATA).getElement(TICK_DATA)
print("TIME\t\t\t\tTYPE\tVALUE\t\tSIZE\tCC")
print("----\t\t\t\t----\t-----\t\t----\t--")
for item in data.values():
time = item.getElementAsDatetime(TIME)
timeString = item.getElementAsString(TIME)
type = item.getElementAsString(TYPE)
value = item.getElementAsFloat(VALUE)
size = item.getElementAsInteger(TICK_SIZE)
if item.hasElement(COND_CODE):
cc = item.getElementAsString(COND_CODE)
else:
cc = ""
print("%s\t%s\t%.3f\t\t%d\t%s" % (timeString, type, value, size, cc))
def processResponseEvent(event):
for msg in event:
print(msg)
if msg.hasElement(RESPONSE_ERROR):
printErrorInfo("REQUEST FAILED: ", msg.getElement(RESPONSE_ERROR))
continue
processMessage(msg)
def sendIntradayTickRequest(session, options, identity = None):
refDataService = session.getService("//blp/refdata")
request = refDataService.createRequest("IntradayTickRequest")
# only one security/eventType per request
request.set("security", options.security)
# Add fields to request
eventTypes = request.getElement("eventTypes")
for event in options.events:
eventTypes.appendValue(event)
# All times are in GMT
if not options.startDateTime or not options.endDateTime:
tradedOn = getPreviousTradingDate()
if tradedOn:
startTime = datetime.datetime.combine(tradedOn,
datetime.time(15, 30))
request.set("startDateTime", startTime)
endTime = datetime.datetime.combine(tradedOn,
datetime.time(15, 35))
request.set("endDateTime", endTime)
else:
if options.startDateTime and options.endDateTime:
request.set("startDateTime", options.startDateTime)
request.set("endDateTime", options.endDateTime)
if options.conditionCodes:
request.set("includeConditionCodes", True)
print("Sending Request:", request)
session.sendRequest(request, identity)
def eventLoop(session):
done = False
while not done:
# nextEvent() method below is called with a timeout to let
# the program catch Ctrl-C between arrivals of new events
event = session.nextEvent(500)
if event.eventType() == blpapi.Event.PARTIAL_RESPONSE:
print("Processing Partial Response")
processResponseEvent(event)
elif event.eventType() == blpapi.Event.RESPONSE:
print("Processing Response")
processResponseEvent(event)
done = True
else:
for msg in event:
if event.eventType() == blpapi.Event.SESSION_STATUS:
if msg.messageType() == SESSION_TERMINATED:
done = True
def getPreviousTradingDate():
tradedOn = datetime.date.today()
while True:
try:
tradedOn -= datetime.timedelta(days=1)
except OverflowError:
return None
if tradedOn.weekday() not in [5, 6]:
return tradedOn
def main():
options = parseCmdLine()
# Fill SessionOptions
sessionOptions = blpapi.SessionOptions()
sessionOptions.setServerHost(options.host)
sessionOptions.setServerPort(options.port)
sessionOptions.setAuthenticationOptions(options.auth)
print("Connecting to %s:%s" % (options.host, options.port))
# Create a Session
session = blpapi.Session(sessionOptions)
# Start a Session
if not session.start():
print("Failed to start session.")
return
identity = None
if options.auth:
identity = session.createIdentity()
isAuthorized = False
authServiceName = "//blp/apiauth"
if session.openService(authServiceName):
authService = session.getService(authServiceName)
isAuthorized = authorize(
authService, identity, session,
blpapi.CorrelationId("auth"))
if not isAuthorized:
print("No authorization")
return
try:
# Open service to get historical data from
if not session.openService("//blp/refdata"):
print("Failed to open //blp/refdata")
return
sendIntradayTickRequest(session, options, identity)
print(sendIntradayTickRequest(session, options, identity))
# wait for events from session.
eventLoop(session)
finally:
# Stop the session
session.stop()
if __name__ == "__main__":
print("IntradayTickExample")
try:
main()
except KeyboardInterrupt:
print("Ctrl+C pressed. Stopping...")
__copyright__ = """
Copyright 2012. Bloomberg Finance L.P.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above
copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
"""
I realized I have been trying to connect to the Server API instead of connectiong to the local terminal. For example, the following code works perfectly:
# SimpleHistoryExample.py
from __future__ import print_function
from __future__ import absolute_import
import blpapi
from optparse import OptionParser
def parseCmdLine():
parser = OptionParser(description="Retrieve reference data.")
parser.add_option("-a",
"--ip",
dest="host",
help="server name or IP (default: %default)",
metavar="ipAddress",
default="localhost")
parser.add_option("-p",
dest="port",
type="int",
help="server port (default: %default)",
metavar="tcpPort",
default=8194)
(options, args) = parser.parse_args()
return options
def main():
options = parseCmdLine()
# Fill SessionOptions
sessionOptions = blpapi.SessionOptions()
sessionOptions.setServerHost(options.host)
sessionOptions.setServerPort(options.port)
print("Connecting to %s:%s" % (options.host, options.port))
# Create a Session
session = blpapi.Session(sessionOptions)
# Start a Session
if not session.start():
print("Failed to start session.")
return
try:
# Open service to get historical data from
if not session.openService("//blp/refdata"):
print("Failed to open //blp/refdata")
return
# Obtain previously opened service
refDataService = session.getService("//blp/refdata")
# Create and fill the request for the historical data
request = refDataService.createRequest("HistoricalDataRequest")
request.getElement("securities").appendValue("EURUSD Curncy")
request.getElement("fields").appendValue("PX_LAST")
request.set("periodicityAdjustment", "ACTUAL")
request.set("periodicitySelection", "DAILY")
request.set("startDate", "20000102")
request.set("endDate", "20191031")
request.set("maxDataPoints", 100000)
print("Sending Request:", request)
# Send the request
session.sendRequest(request)
# Process received events
while(True):
# We provide timeout to give the chance for Ctrl+C handling:
ev = session.nextEvent(500)
for msg in ev:
print(msg)
if ev.eventType() == blpapi.Event.RESPONSE:
# Response completly received, so we could exit
break
finally:
# Stop the session
session.stop()
if __name__ == "__main__":
print("SimpleHistoryExample")
try:
main()
except KeyboardInterrupt:
print("Ctrl+C pressed. Stopping...")
I'm writing a Ryu a L4 swtich application and i am trying to do the following: when a TCP/UDP packet is identified the application checks in a local database to see if the packet parameters are from a known attacker (source IP, destination IP and destination port).
If the packet matches one logged in the attacker database a flow is added to the switch to drop the specific packet (this flow has a duration of 2 hours), if the packet doesn't match a flow is added to forward to a specific switch port (this flow has a duration of 5 minutes).
The problem is, when the controller sends the new flow to the switch/datapath i receive the following error:
SimpleSwitch13: Exception occurred during handler processing. Backtrace from offending handler [_packet_in_handler] servicing event [EventOFPPacketIn] follows.
Traceback (most recent call last):
File "/root/SecAPI/Code/lib/python3.5/site-packages/ryu/base/app_manager.py", line 290, in _event_loop
handler(ev)
File "/root/SecAPI/Flasks/Code/SDN/switchL3.py", line 237, in _packet_in_handler
self.add_security_flow(datapath, 1, match, actions)
File "/root/SecAPI/Flasks/Code/SDN/switchL3.py", line 109, in add_security_flow
datapath.send_msg(mod)
File "/root/SecAPI/Code/lib/python3.5/site-packages/ryu/controller/controller.py", line 423, in send_msg
msg.serialize()
File "/root/SecAPI/Code/lib/python3.5/site-packages/ryu/ofproto/ofproto_parser.py", line 270, in serialize
self._serialize_body()
File "/root/SecAPI/Code/lib/python3.5/site-packages/ryu/ofproto/ofproto_v1_3_parser.py", line 2738, in _serialize_body
self.out_group, self.flags)
File "/root/SecAPI/Code/lib/python3.5/site-packages/ryu/lib/pack_utils.py", line 25, in msg_pack_into
struct.pack_into(fmt, buf, offset, *args)
struct.error: 'H' format requires 0 <= number <= 65535
heres my full code:
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import ether_types
from ryu.lib.packet import ipv4
from ryu.lib.packet import tcp
from ryu.lib.packet import udp
from ryu.lib.packet import in_proto
import sqlite3
class SimpleSwitch13(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(SimpleSwitch13, self).__init__(*args, **kwargs)
self.mac_to_port = {}
self.initial = True
self.security_alert = False
#set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
datapath = ev.msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
match = parser.OFPMatch()
self.initial = True
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath, 0, match, actions)
self.initial = False
# Adds a flow into a specific datapath, with a hard_timeout of 5 minutes.
# Meaning that a certain packet flow ceases existing after 5 minutes.
def add_flow(self, datapath, priority, match, actions, buffer_id=None):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
actions)]
if buffer_id:
if self.initial == True:
mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id,
priority=priority, match=match,
instructions=inst)
elif self.initial == False:
mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id,
priority=priority, match=match,
instructions=inst,hard_timeout=300)
else:
if self.initial == True:
mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
match=match, instructions=inst)
elif self.initial == False:
mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
match=match, instructions=inst,
hard_timeout=300)
datapath.send_msg(mod)
# Adds a security flow into the controlled device, a secured flow differs from a normal
# flow in it's duration, a security flow has a duration of 2 hours.
def add_security_flow(self, datapath, priority, match, actions, buffer_id=None):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
#inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
# actions)]
inst = [parser.OFPInstructionActions(ofproto.OFPIT_CLEAR_ACTIONS, [])]
if buffer_id:
mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id,
priority=priority,match=match,command=ofproto.OFPFC_ADD,
instructions=inst, hard_timeout=432000)
else:
mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
match=match, instructions=inst, command=ofproto.OFPFC_ADD,
hard_timeout=432000)
datapath.send_msg(mod)
# Deletes a already existing flow that matches has a given packet match.
def del_flow(self, datapath, priority, match, actions, buffer_id=None):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
actions)]
if buffer_id:
mod = parser.OFPFlowMod(datapath=datapath,buffer_id=buffer_id,
priority=priority,match=match,instruction=inst,
command=ofproto.OFPFC_DELETE)
else:
mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
match=match, instructions=inst,
command=ofproto.OFPFC_DELETE)
datapath.send_msg(mod)
#set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
# If you hit this you might want to increase
# the "miss_send_length" of your switch
if ev.msg.msg_len < ev.msg.total_len:
self.logger.debug("packet truncated: only %s of %s bytes",
ev.msg.msg_len, ev.msg.total_len)
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
eth = pkt.get_protocols(ethernet.ethernet)[0]
if eth.ethertype == ether_types.ETH_TYPE_LLDP:
# ignore lldp packet
return
dst = eth.dst
src = eth.src
dpid = datapath.id
self.mac_to_port.setdefault(dpid, {})
self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
# learn a mac address to avoid FLOOD next time.
self.mac_to_port[dpid][src] = in_port
if dst in self.mac_to_port[dpid]:
out_port = self.mac_to_port[dpid][dst]
else:
out_port = ofproto.OFPP_FLOOD
actions = [parser.OFPActionOutput(out_port)]
# install a flow to avoid packet_in next time
if out_port != ofproto.OFPP_FLOOD:
#match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src)
# check IP Protocol and create a match for IP
if eth.ethertype == ether_types.ETH_TYPE_IP:
conn = sqlite3.connect("database/sdnDatabase.db")
cursor = conn.cursor()
ip = pkt.get_protocol(ipv4.ipv4)
srcip = ip.src
dstip = ip.dst
#match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP,ipv4_src=srcip,ipv4_dst=dstip)
protocol = ip.proto
# ICMP Protocol
if protocol == in_proto.IPPROTO_ICMP:
print("WARN - We have a ICMP packet")
cursor.execute('select id from knownAttackers where srcaddr = \"{0}\" and dstaddr = \"{1}\" and protocol = "icmp";'.format(srcip, dstip))
result = cursor.fetchall()
match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip, ipv4_dst=dstip,
ip_proto=protocol)
if len(result) == 0:
self.security_alert = False
else:
self.security_alert = True
# TCP Protocol
elif protocol == in_proto.IPPROTO_TCP:
print("WARN - We have a TCP packet")
t = pkt.get_protocol(tcp.tcp)
cursor.execute('select id from knownAttackers where srcaddr = \"{0}\" and dstaddr = \"{1}\" and dstport = \"{2}\" and protocol = "tcp";'.format(srcip, dstip, t.dst_port))
result = cursor.fetchall()
match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip, ipv4_dst=dstip,
ip_proto=protocol, tcp_dst=t.dst_port)
if len(result) == 0:
self.security_alert = False
else:
print("We have a register in the database for this specific packet: {0}".format(result))
self.security_alert = True
# UDP Protocol
elif protocol == in_proto.IPPROTO_UDP:
print("WARN - We have a UDP packet")
u = pkt.get_protocol(udp.udp)
cursor.execute('select id from knownAttackers where srcaddr = \"{0}\" and dstaddr = \"{1}\" and dstport = \"{2}\" and protocol = "udp";'.format(srcip, dstip, u.dst_port))
result = cursor.fetchall()
match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip, ipv4_dst=dstip,
ip_proto=protocol, udp_dst=u.dst_port)
if len(result) == 0:
self.security_alert = False
else:
self.security_alert = True
else:
self.security_alert = False
match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src)
# verify if we have a valid buffer_id, if yes avoid to send both
# flow_mod & packet_out
if self.security_alert == False:
if msg.buffer_id != ofproto.OFP_NO_BUFFER:
self.add_flow(datapath, 1, match, actions, msg.buffer_id)
return
else:
self.add_flow(datapath, 1, match, actions)
elif self.security_alert == True:
if msg.buffer_id != ofproto.OFP_NO_BUFFER:
self.add_security_flow(datapath, 1, match, actions, msg.buffer_id)
return
else:
self.add_security_flow(datapath, 1, match, actions)
data = None
if msg.buffer_id == ofproto.OFP_NO_BUFFER:
data = msg.data
if self.security_alert == False:
out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
in_port=in_port, actions=actions, data=data)
datapath.send_msg(out)
the above error appears in the end of the add_security_flow() class method when i try to make a TCP connection that is identified as a known attacker, when he tries to send the flow modification (datapath.send_msg(mod)) to the switch/datapath.
What am i doing wrong? Am i'm missing some sort of variable?
In the Ryu controller mailing list a user named IWAMOTO told me that my hard_timeout values was too large for the struct packing (2 hours is 7200 seconds, i dont know where my head was for me to find 432000 haha), after downsizing the hard_timeout to 7200 seconds everything worked out just fine.
Always check the size of the values you're trying to send to a datapath, see if it doesn't exceed 65535.
I am using Quickfix and I modified my toAdmin function to insert the username and password into the logon message. I adapted my code from the c++ instructions but I got a weird getHeader() attribute error.
The traceback is the following :
<20151223-10:48:31.142, FIX.4.2:MATHCLIENT1->CSTEST, event>
(Created session)
Type 1 for order , 2 to exit and d to debug.
<20151223-10:48:31.149, FIX.4.2:CLIENT1->TEST, event>
(Connecting to hostX on port Y)
Traceback (most recent call last):
File "initiator.py", line 28, in toAdmin
message.getHeader ().getField (msgType)
File "C:\Users\user\Anaconda\lib\site-packages\quickfix.py", line 27015, in <lambda>
__getattr__ = lambda self, name: _swig_getattr(self, SessionID, name)
File "C:\Users\user\Anaconda\lib\site-packages\quickfix.py", line 57, in _swig_getattr
raise AttributeError(name)
AttributeError: getHeader
My code follows below :
import sys
import time
import thread
import argparse
from datetime import datetime
import quickfix as fix
class Application(fix.Application):
orderID = 0
execID = 0
def gen_ord_id(self):
global orderID
orderID+=1
return orderID
def onCreate(self, sessionID):
return
def onLogon(self, sessionID):
self.sessionID = sessionID
print ("Successful Logon to session '%s'." % sessionID.toString())
return
def onLogout(self, sessionID): return
def toAdmin(self, sessionID, message):
msgType = fix.MsgType ()
message.getHeader ().getField (msgType)
if (msgType.getValue () == fix.MsgType_Logon):
print 'Logging on.'
# message.setField (fix.Password (settings.get (self.sessionID).getString ("Password")))
# message.setField (fix.Username (settings.get (self.sessionID).getString ("Username")))
message.setField(fix.Password('password'))
message.setField(fix.Username('username'))
message.setField (fix.ResetSeqNumFlag (True))
return
def fromAdmin(self, sessionID, message):
return
def toApp(self, sessionID, message):
print "Sent the following message: %s" % message.toString()
return
def fromApp(self, message, sessionID):
print "Received the following message: %s" % message.toString()
return
def genOrderID(self):
self.orderID = self.orderID+1
return `self.orderID`
def genExecID(self):
self.execID = self.execID+1
return `self.execID`
def put_order(self):
print("Creating the following order: ")
trade = fix.Message()
trade.getHeader().setField(fix.BeginString(fix.BeginString_FIX50)) #
trade.getHeader().setField(fix.MsgType(fix.MsgType_NewOrderSingle)) #39=D
trade.setField(fix.ClOrdID(self.genExecID())) #11=Unique order
trade.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION)) #21=3 (Manual order, best executiona)
trade.setField(fix.Symbol('SMBL')) #55=SMBL ?
trade.setField(fix.Side(fix.Side_BUY)) #43=1 Buy
trade.setField(fix.OrdType(fix.OrdType_LIMIT)) #40=2 Limit order
trade.setField(fix.OrderQty(100)) #38=100
trade.setField(fix.Price(10))
print trade.toString()
fix.Session.sendToTarget(trade, self.sessionID)
def main(config_file):
try:
settings = fix.SessionSettings(config_file)
application = Application()
storeFactory = fix.FileStoreFactory(settings)
# logFactory = fix.FileLogFactory(settings)
logFactory = fix.ScreenLogFactory(settings)
initiator = fix.SocketInitiator(application, storeFactory, settings, logFactory)
initiator.start()
print 'Type 1 for order , 2 to exit and d to debug.'
while 1:
input = raw_input()
if input == '1':
print "Putin Order"
application.put_order()
if input == '2':
sys.exit(0)
if input == 'd':
import pdb
pdb.set_trace()
else:
print "Valid input is 1 for order, 2 for exit"
continue
except (fix.ConfigError, fix.RuntimeError), e:
print e
if __name__=='__main__':
# logfile = open('errorlog.txt','w')
# original_stderr = sys.stderr
# sys.stderr = logfile
parser = argparse.ArgumentParser(description='FIX Client')
parser.add_argument('file_name', type=str, help='Name of configuration file')
args = parser.parse_args()
main(args.file_name)
# sys.stderr = original_stderr
# logfile.close()
This looks mostly correct, however, I believe you have entered your arguments in the wrong order. Try defining your function as follows:
def toAdmin(self, message, sessionID):
I have been experimenting with QuickFix but I am getting a "AttributeError:SessionID". I honestly have no idea why it's happening, I tinkered with the code a bit but problem remains. Also , google has failed me big on this one so I hope you guys can help me.
Code :
import sys
import time
import thread
import argparse
from datetime import datetime
import quickfix as fix
class Application(fix.Application):
orderID = 0
execID = 0
def gen_ord_id(self):
global orderID
orderID+=1
return orderID
def onCreate(self, sessionID):
return
def onLogon(self, sessionID):
self.sessionID = sessionID
print ("Successful Logon to session '%s'." % sessionID.toString())
return
def onLogout(self, sessionID): return
def toAdmin(self, sessionID, message):
return
def fromAdmin(self, sessionID, message):
return
def toApp(self, sessionID, message):
print "Sent the following message: %s" % message.toString()
return
def fromApp(self, message, sessionID):
print "Received the following message: %s" % message.toString()
return
def genOrderID(self):
self.orderID = self.orderID+1
return `self.orderID`
def genExecID(self):
self.execID = self.execID+1
return `self.execID`
def put_order(self):
print("Creating the following order: ")
trade = fix.Message()
trade.getHeader().setField(fix.BeginString(fix.BeginString_FIX50)) #
trade.getHeader().setField(fix.MsgType(fix.MsgType_NewOrderSingle)) #39=D
trade.setField(fix.ClOrdID(self.genExecID())) #11=Unique order
trade.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION)) #21=3 (Manual order, best executiona)
trade.setField(fix.Symbol('SMBL')) #55=SMBL ?
trade.setField(fix.Side(fix.Side_BUY)) #43=1 Buy
trade.setField(fix.OrdType(fix.OrdType_LIMIT)) #40=2 Limit order
trade.setField(fix.OrderQty(100)) #38=100
trade.setField(fix.Price(10))
print trade.toString()
fix.Session.sendToTarget(trade, self.sessionID)
def main(config_file):
try:
settings = fix.SessionSettings("initiatorsettings.cfg")
application = Application()
storeFactory = fix.FileStoreFactory(settings)
logFactory = fix.FileLogFactory(settings)
initiator = fix.SocketInitiator(application, storeFactory, settings, logFactory)
initiator.start()
while 1:
input = raw_input()
if input == '1':
print "Putin Order"
application.put_order()
if input == '2':
sys.exit(0)
if input == 'd':
import pdb
pdb.set_trace()
else:
print "Valid input is 1 for order, 2 for exit"
continue
except (fix.ConfigError, fix.RuntimeError), e:
print e
if __name__=='__main__':
parser = argparse.ArgumentParser(description='FIX Client')
parser.add_argument('file_name', type=str, help='Name of configuration file')
args = parser.parse_args()
main(args.file_name)
I get the following error message :
Traceback (most recent call last):
File "initiator.py", line 97, in main application.put_order()
File "initiator.py", line 80, in put_order fix.Session.sendToTarget(trade, self.sessionID)
File "C:\Users\gribeiro\Anaconda\lib\site-packages\quickfix.py", line 30939, in <lambda>__getattr__ = lambda self, name: _swig_getattr(self, Application, name)
File "C:\Users\gribeiro\Anaconda\lib\site-packages\quickfix.py", line 57, in _swig_getattr raise AttributeError(name)
AttributeError: sessionID
------------------------------------------------------------
Update :
Code producing the error:
import sys
import time
import thread
import argparse
from datetime import datetime
import quickfix as fix
class Application(fix.Application):
orderID = 0
execID = 0
def gen_ord_id(self):
global orderID
orderID+=1
return orderID
def onCreate(self, sessionID):
return
def onLogon(self, sessionID):
# self.sessionID = sessionID
# print ("Successful Logon to session '%s'." % sessionID.toString())
return
def onLogout(self, sessionID): return
def toAdmin(self, sessionID, message):
return
def fromAdmin(self, sessionID, message):
return
def toApp(self, sessionID, message):
print "Sent the following message: %s" % message.toString()
return
def fromApp(self, message, sessionID):
print "Received the following message: %s" % message.toString()
return
def genOrderID(self):
self.orderID = self.orderID+1
return `self.orderID`
def genExecID(self):
self.execID = self.execID+1
return `self.execID`
def put_order(self):
print("Creating the following order: ")
trade = fix.Message()
trade.getHeader().setField(fix.BeginString(fix.BeginString_FIX50)) #
trade.getHeader().setField(fix.MsgType(fix.MsgType_NewOrderSingle)) #39=D
trade.setField(fix.ClOrdID(self.genExecID())) #11=Unique order
trade.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION)) #21=3 (Manual order, best executiona)
trade.setField(fix.Symbol('SMBL')) #55=SMBL ?
trade.setField(fix.Side(fix.Side_BUY)) #43=1 Buy
trade.setField(fix.OrdType(fix.OrdType_LIMIT)) #40=2 Limit order
trade.setField(fix.OrderQty(100)) #38=100
trade.setField(fix.Price(10))
print trade.toString()
fix.Session_sendToTarget(trade)
def main(config_file):
try:
settings = fix.SessionSettings(config_file)
application = Application()
storeFactory = fix.FileStoreFactory(settings)
logFactory = fix.FileLogFactory(settings)
initiator = fix.SocketInitiator(application, storeFactory, settings, logFactory)
initiator.start()
while 1:
input = raw_input()
if input == '1':
print "Putin Order"
application.put_order()
if input == '2':
sys.exit(0)
if input == 'd':
import pdb
pdb.set_trace()
else:
print "Valid input is 1 for order, 2 for exit"
continue
except (fix.ConfigError, fix.RuntimeError), e:
print e
if __name__=='__main__':
parser = argparse.ArgumentParser(description='FIX Client')
parser.add_argument('file_name', type=str, help='Name of configuration file')
args = parser.parse_args()
main(args.file_name)
Config file :
[DEFAULT]
ConnectionType=initiator
ReconnectInterval=60
FileStorePath=store
FileLogPath=log
StartTime=00:00:00
EndTime=00:00:00
UseDataDictionary=Y
DataDictionary=spec/FIX42.xml
HttpAcceptPort=9911
ValidateUserDefinedFields=N
ResetOnLogout=Y
ResetOnLogon=Y
ValidateFieldsOutOfOrder=N
DefaultApplVerID=FIX.5.0SP2
# standard config elements
[SESSION]
# inherit ConnectionType, ReconnectInterval and SenderCompID from default
BeginString=FIX.4.2
SenderCompID=BRANZOL
TargetCompID=FIXSIM
SocketConnectHost=host
SocketConnectPort=port
HeartBtInt=30
Output from ScreenLogFactory >
<20151216-17:09:43.426, FIX.4.2:BRANZOL->FIXSIM, event>
(Created session)
<20151216-17:09:43.434, FIX.4.2:BRANZOL->FIXSIM, event>
(Connecting to hostX on port Y)
<20151216-17:09:44.159, FIX.4.2:BRANZOL->FIXSIM, outgoing>
(8=FIX.4.29=7435=A34=149=BRANZOL52=20151216-17:09:43.88256=FIXSIM98=0108=30141=Y10=032)
<20151216-17:09:44.159, FIX.4.2:BRANZOL->FIXSIM, event>
(Initiated logon request)
<20151216-17:09:44.264, FIX.4.2:BRANZOL->FIXSIM, event>
(Socket Error: Connection reset by peer.)
<20151216-17:09:44.264, FIX.4.2:BRANZOL->FIXSIM, event>
(Disconnecting)
Valid input is 1 for order, 2 for exit
Putin Order
Creating the following order:
8=FIX.5.09=4635=D11=121=338=10040=244=1054=155=SMBL10=081
Try cutting this line entirely self.sessionID = sessionID
EDIT -- OKay, thanks for including the traceback. You should replace the line fix.Session.sendToTarget(trade, self.sessionID) with the line fix.Session_sendToTarget(trade) and let me know how that goes.
Background:
I would like to integrate yowsup to my home automation project. I have seen a simple sample on how to receive messages and after some minor changes it is working fine.
Issue:
My problem starts when it comes to integrate the send message feature. Those are the two files I am using:
run.py
from layer import EchoLayer
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.layers.protocol_messages import YowMessagesProtocolLayer
from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer
from yowsup.layers.protocol_acks import YowAckProtocolLayer
from yowsup.layers.protocol_presence import YowPresenceProtocolLayer
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.coder import YowCoderLayer
from yowsup.common import YowConstants
from yowsup.layers import YowLayerEvent
from yowsup.stacks import YowStack, YOWSUP_CORE_LAYERS
from yowsup import env
CREDENTIALS = ("phone", "pwd")
if __name__ == "__main__":
layers = (
EchoLayer,
(YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer, YowPresenceProtocolLayer)
) + YOWSUP_CORE_LAYERS
stack = YowStack(layers)
# Setting credentials
stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS)
# WhatsApp server address
stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0])
stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)
stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource())
# Sending connecting signal
stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
# Program main loop
stack.loop()
layer.py
from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity
from yowsup.layers.protocol_presence.protocolentities import PresenceProtocolEntity
import threading
import logging
logger = logging.getLogger(__name__)
class EchoLayer(YowInterfaceLayer):
#ProtocolEntityCallback("message")
def onMessage(self, messageProtocolEntity):
#send receipt otherwise we keep receiving the same message over and over
print str(messageProtocolEntity.getFrom()) + ' - ' + str(messageProtocolEntity.getBody())
receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom())
self.toLower(receipt)
#ProtocolEntityCallback("send_message")
def sendMessage(self, destination, message, messageProtocolEntity):
outgoingMessageProtocolEntity = TextMessageProtocolEntity(
message,
to = destination + "#s.whatsapp.net")
self.toLower(outgoingMessageProtocolEntity)
#ProtocolEntityCallback("receipt")
def onReceipt(self, entity):
ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", "delivery")
self.toLower(ack)
# List of (jid, message) tuples
PROP_MESSAGES = "org.openwhatsapp.yowsup.prop.sendclient.queue"
def __init__(self):
super(EchoLayer, self).__init__()
self.ackQueue = []
self.lock = threading.Condition()
#ProtocolEntityCallback("success")
def onSuccess(self, successProtocolEntity):
self.lock.acquire()
for target in self.getProp(self.__class__.PROP_MESSAGES, []):
phone, message = target
if '#' in phone:
messageEntity = TextMessageProtocolEntity(message, to = phone)
elif '-' in phone:
messageEntity = TextMessageProtocolEntity(message, to = "%s#g.us" % phone)
else:
messageEntity = TextMessageProtocolEntity(message, to = "%s#s.whatsapp.net" % phone)
self.ackQueue.append(messageEntity.getId())
self.toLower(messageEntity)
self.lock.release()
#ProtocolEntityCallback("ack")
def onAck(self, entity):
self.lock.acquire()
if entity.getId() in self.ackQueue:
self.ackQueue.pop(self.ackQueue.index(entity.getId()))
if not len(self.ackQueue):
logger.info("Message sent")
#raise KeyboardInterrupt()
self.lock.release()
Questions:
Where am I supposed to call the send_message method, so I can send messages wherever I need it?
Is there a regular event (triggering every second or something) which I could use to send my messages?
#ProtocolEntityCallback("send_message")
def sendMessage(self, destination, message, messageProtocolEntity):
outgoingMessageProtocolEntity = TextMessageProtocolEntity(
message,
to = destination + "#s.whatsapp.net")
self.toLower(outgoingMessageProtocolEntity)
In the avove code sendMessage to be called, protocolEntity.getTag() == "send_message" has to be True. You don't need it to send message.
layer.py
from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity
from yowsup.layers.protocol_presence.protocolentities import PresenceProtocolEntity
import threading
import logging
logger = logging.getLogger(__name__)
recv_msg = []
class EchoLayer(YowInterfaceLayer):
def __init__(self):
super(EchoLayer, self).__init__()
self.ackQueue = []
self.lock = threading.Condition()
#ProtocolEntityCallback("message")
def onMessage(self, messageProtocolEntity):
if messageProtocolEntity.getType() == 'text':
recv_msg.append((messageProtocolEntity.getFrom(),messageProtocolEntity.getBody()))
#send receipt otherwise we keep receiving the same message over and over
receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom())
self.toLower(receipt)
#ProtocolEntityCallback("receipt")
def onReceipt(self, entity):
ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", "delivery")
self.toLower(ack)
# List of (jid, message) tuples
PROP_MESSAGES = "org.openwhatsapp.yowsup.prop.sendclient.queue"
#ProtocolEntityCallback("success")
def onSuccess(self, successProtocolEntity):
self.lock.acquire()
for target in self.getProp(self.__class__.PROP_MESSAGES, []):
phone, message = target
if '#' in phone:
messageEntity = TextMessageProtocolEntity(message, to = phone)
elif '-' in phone:
messageEntity = TextMessageProtocolEntity(message, to = "%s#g.us" % phone)
else:
messageEntity = TextMessageProtocolEntity(message, to = "%s#s.whatsapp.net" % phone)
self.ackQueue.append(messageEntity.getId())
self.toLower(messageEntity)
self.lock.release()
#ProtocolEntityCallback("ack")
def onAck(self, entity):
self.lock.acquire()
if entity.getId() in self.ackQueue:
self.ackQueue.pop(self.ackQueue.index(entity.getId()))
if not len(self.ackQueue):
self.lock.release()
logger.info("Message sent")
raise KeyboardInterrupt()
self.lock.release()
To send message define a function send_message in the stack run.py. You can also import run.py and use it's function from other script.
from layer import EchoLayer, recv_msg
CREDENTIALS = ("phone", "pwd")
def send_message(destination, message):
'''
destination is <phone number> without '+'
and with country code of type string,
message is string
e.g send_message('11133434343','hello')
'''
messages = [(destination, message)]
layers = (EchoLayer,
(YowAuthenticationProtocolLayer,
YowMessagesProtocolLayer,
YowReceiptProtocolLayer,
YowAckProtocolLayer,
YowPresenceProtocolLayer)
) + YOWSUP_CORE_LAYERS
stack = YowStack(layers)
stack.setProp(EchoLayer.PROP_MESSAGES, messages)
stack.setProp(YowAuthenticationProtocolLayer.PROP_PASSIVE, True)
# Setting credentials
stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS)
# WhatsApp server address
stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0])
stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)
stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource())
# Sending connecting signal
stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
try:
# Program main loop
stack.loop()
except AuthError as e:
print('Authentication error %s' % e.message)
sys.exit(1)
def recv_message():
layers = ( EchoLayer,
(YowAuthenticationProtocolLayer, YowMessagesProtocolLayer,
YowReceiptProtocolLayer, YowAckProtocolLayer,
YowPresenceProtocolLayer)
) + YOWSUP_CORE_LAYERS
stack = YowStack(layers)
# Setting credentials
stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS)
# WhatsApp server address
stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0])
stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)
stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource())
# Sending connecting signal
stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
try:
# Program main loop
stack.loop()
except AuthError as e:
print('Authentication error %s' % e.message)
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) == 1:
print('%s send number message\nrecv\n' % sys.argv[0])
sys.exit(1)
if sys.argv[1] == 'send':
try:
send_message(sys.argv[2],sys.argv[3])
except KeyboardInterrupt:
print('closing')
sys.exit(0)
if sys.argv[1] == 'recv':
try:
recv_message()
except KeyboardInterrupt:
print('closing')
sys.exit(0)
for m in recv_msg:
print('From %s:\n%s\n' % m)
Now you can send message by calling send_message('1234567890','Howdy') and recieve message by calling recv_message().