Tell me how I can understand what is in the handler Client.Update. Is the message coming from me?
For some reason, it happens that I look at the From_id and From.Id, there is my ID, then for some reason, there is not.
As I understand it, it shows my ID when I write in a chat, and if in private messages with a friend, it shows his ID.
I'm trying to catch the ID through a common example.
private static void DisplayMessage(MessageBase messageBase, bool edit = false)
{
if (edit) Console.Write("(Edit): ");
switch (messageBase)
{
case Message m: Console.WriteLine($"{Peer(m.from_id) ?? m.post_author} in {Peer(m.peer_id)}> {m.message}"); break;
case MessageService ms: Console.WriteLine($"{Peer(ms.from_id)} in {Peer(ms.peer_id)} [{ms.action.GetType().Name[13..]}]"); break;
}
}
The message.flags should contain the flag Flags.out_ for your outgoing messages.
Related
So at work I inherited a massive project taking 1553 messages from an airplane and translating them to a completely different message type. My problem is that I need to use the data from 2 different messages, which are processed completely separately, together.
This is how I inherited it: there's a completely different process for processing the 2Rx message (which has the "plane altitude" data) and the 17Rx message (which has the "structure altitude" data).
I tried to simplify as much of the code that's relevant as possible, but this is the first experience I've had with coding and I've had no programming education, so please tell me if there's something I can do to make it more clear (for example I don't fully understand the Process1553 function).
My job is to do the actual conversions: in my example the altitude data for both the plane and a ground structure is being received in meters and needs to be sent out as feet. However, I ALSO need to send out data comparing the 2 altitudes (well, I'm actually converting Lat/Long/Alt to North/East/Down, but for simplicity let's just say I need the difference in altitudes of the plane and the structure).
void AirplaneComm::Process1553()
{
M1553RawMsgClass *currentMessage;
//check for new messages
while(incomingMessages->size()>0)
{
//grab the message from the top of the stack
currentMessage=(M1553RawMsgClass*)incomingMessages->front();
//pop the stack
incomingMessages->pop_front();
//We are only interested in R messages
if(currentMessage->MessageType()==M1553RawMsgClass::RECEIVE_MSG)
{
M1553RxMsgClass newRxMessage(*currentMessage);
switch (newRxMessage.RxMsgType())
{
case M1553RxMsgClass::RX_2: {
ProcessRx2Msg(newRxMessage);
break;}
// .... more messages
case M1553RxMsgClass::RX_17: {
ProcessRx17Msg(newRxMessage);
break;}
default:
// No processing for this message
break;
}
}
//clean up
if(currentMessage)
{
delete currentMessage;
}
}
}
void AirplaneComm::ProcessRx2Msg(M1553RxMsgClass incoming2Rmessage)
{
M1760Rx2MsgClass newMessage(incoming2Rmessage); //M1760 classes "get" data from
//the 1553 messages and "set"
//it to send as serial
WordType platformAltitudeMeters = newMessage.GetPlatAltitude(); //received altitude in meters
double platformAltitudeFeet = platformAltitudeMeters * 3.2808; //converted to feet
mSerial.SetPlatAltitude(platformAltitudeFeet); //sets the altitude info
}
void AirplaneComm::ProcessRx17Msg(M1553RxMsgClass incoming17Rmessage)
{
M1760Rx17MsgClass newMessage(incoming17Rmessage);
WordType structureAltitudeMeters = newMessage.GetStructAltitude(); //received altitude in meters
double structureAltitudeFeet = structureAltitudeMeters * 3.2808; //converted to feet
mSerial.SetStructAltitude(structureAltitudeFeet); //sets the altitude info
}
So as far as I can tell, the "switch" function takes each "case" individually. I tried creating a new 2Rx AND 17Rx process ("ProcessRx2MsgRx17Msg") assigning those messages (Rx2Msg, Rx17Msg) to variables I declared in each "case":
switch (newRxMessage.RxMsgType())
{
case M1553RxMsgClass::RX_2:
ProcessRx2Msg(newRxMessage);
M1553RxMsgClass Rx2Msg; //M1553RxMsgClass is a variable type taking
Rx2Msg = newRxMessage; //the whole message
break;}
case M1553RxMsgClass::RX_17:
ProcessRx17Msg(newRxMessage);
M1553RxMsgClass Rx17Msg = newRxMessage;
break;
default:
// No processing for this message
break;
ProcessRx2MsgRx17Msg(Rx2Msg, Rx17Msg);
}
but when I did that, it claimed that I was jumping switch labels. I get that this means they are in the same "scope" (ok, I googled it) but when I put brackets around each "case":
case M1553RxMsgClass::RX_2: {
ProcessRx2Msg(newRxMessage);
M1553RxMsgClass Rx2Msg;
Rx2Msg = newRxMessage;
break;}
case M1553RxMsgClass::RX_17: {
ProcessRx17Msg(newRxMessage);
M1553RxMsgClass Rx17Msg = newRxMessage;
break;}
default:
// No processing for this message
break;
ProcessRx2MsgRx17Msg(Rx2Msg, Rx17Msg);
}
but then my ProcessRx2MsgRx17Msg doesn't recognize "Rx2Msg" or "Rx17Msg".
I also considered making "ProcessRx2Msg" a function that could return a value instead of a void function so that I could use it in "ProcessRx17Msg", but I actually need multiple variables from each message (latitude, longitude, and altitude).
So, is it even possible to accomplish what I want with the way it's set up since I inherited it? Also, sorry if I used the wrong terms for certain things.
EDIT: Thank you JarMan and SoronelHaetir. This is how I ended up getting it to work:
void AirplaneComm::Process1553()
{
M1553RawMsgClass *currentMessage;
static M1553RxMsgClass Rx2Msg, Rx17Msg;
//check for new messages
while(incomingMessages->size()>0)
{
//grab the message from the top of the stack
currentMessage=(M1553RawMsgClass*)incomingMessages->front();
//pop the stack
incomingMessages->pop_front();
//We are only interested in R messages
if(currentMessage->MessageType()==M1553RawMsgClass::RECEIVE_MSG)
{
M1553RxMsgClass newRxMessage(*currentMessage);
switch (newRxMessage.RxMsgType())
{
case M1553RxMsgClass::RX_2:
ProcessRx2Msg(newRxMessage);
Rx2Msg = newRxMessage;
break;
// .... more messages
case M1553RxMsgClass::RX_17:
ProcessRx17Msg(newRxMessage);
Rx17Msg = newRxMessage;
ProcessRx2MsgRx17Msg(Rx2Msg, Rx17Msg);
break;
default:
// No processing for this message
break;
}
}
//clean up
if(currentMessage)
{
delete currentMessage;
}
}
}
Then, I was able to use ProcessRx2MsgRx17Msg to convert the airplane geodetic data from Rx2 AND the structure geodetic data from Rx17 to North/East/Down coordinates.
If you need to process data from multiple messages you will have to alter the earlier message processing to save the needed data somewhere then when the later message comes in refer to both the later message parameters as well as the saved message parameters from the earlier message(s). The saved data will need a lifetime longer than the single function call (whether you make it static to the message processing function or global is up to the design choices your organization uses).
If a user doesn't send enough enough Eth, I'd like the UI to know and respond with a message.
This function validates msg.value, but I'd like to trigger and event (which the UI can respond to) in this case.
function doSomething() external payable {
require(
msg.value == price,
'Please send the correct amount of ETH'
);
//Do something
}
Is this the correct way to do that?
Is there any way to combine require() with sending events?
function doSomething() external payable {
if (msg.value < amount){
emit NotEnoughEth('Please make sure to send correct amount');
revert();
}
//Do something
}
emit NotEnoughEth('Please make sure to send correct amount');
you can't do this.
to be able to emit a types.Log you need your evm.Call() to execute without doing a revert. There are 2 instructions in the EVM you are referring to: makeLog (https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/instructions.go#L828) this is the one that creates and Event log. And opRevert (https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/instructions.go#L806) , so if you do the revert, your Call() will return an error, and all the result of the transaction on ethereum State database will be reverted and nothing will be saved. Since the storage is cancelled, there is no way for your Log to be saved on the blockchain.
This is the code that will check for error, and reverts to previously saved state (aka Snapshot) :
if err != nil {
evm.StateDB.RevertToSnapshot(snapshot)
if err != ErrExecutionReverted {
gas = 0
}
// TODO: consider clearing up unused snapshots:
//} else {
// evm.StateDB.DiscardSnapshot(snapshot)
}
return ret, gas, err
}
https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/evm.go#L280
Even though the opRevert() instruction doesn't explicitly returns an error, the Jump table is configured to always return an error for opRevert :
instructionSet[REVERT] = &operation{
execute: opRevert,
dynamicGas: gasRevert,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
memorySize: memoryRevert,
reverts: true,
returns: true,
}
https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/jump_table.go#L155
and the Interpreter will issue errExecutionReverted on its own:
case operation.reverts:
return res, ErrExecutionReverted
https://github.com/ethereum/go-ethereum/blob/2aaff0ad76991be8851ae30454d2e2e967704102/core/vm/interpreter.go#L297
I have this action it its model file HandlQuestionTimeOut.model.bxb :
action (HandleQuestionTimeOut)
{
type(Calculation)
description (Handles Question Time Out.)
collect
{
input (message)
{
type (core.Text)
min (Required) max (One)
}
}
output (core.Text)
}
This in HandleQuestionTimeOut.js
var console = require("console");
module.exports.function = function handleQuestionTimeOut (message)
{
console.log("handleQuestionTimeOut -> message: " + message);
return message;
}
This in the quiz.endpoints.bxb inside the endpoints bracket:
action-endpoint (HandleQuestionTimeOut)
{
accepted-inputs (message)
local-endpoint (HandleQuestionTimeOut.js)
}
I am trying to call that action with refresh like this:
input-view
{
match: Answer(this)
{
to-input: UpdateQuiz(action)
}
refresh
{
if(true)
{
spec
{
delay-seconds (3)
with-request
{
intent
{
goal {HandleQuestionTimeOut}
value: core.Text(Timeout)
}
}
}
}
}
// code continues...
Can you please tell what am I doing wrong? I don't get that HandleQuestionTimeOut log in the console.
Can you clarify you questions?
Though I noticed something, based on my personal opinion:
1) correct module.exports.function -> module.export.function
2) In the refresh section I think you need to specify condition for 'true' or is it there for debugging purpose?
I've just verified that this issue is fixed in 20B SDK release.
Please refer the release notes for details about other changes.
I am using quickfix C++ implementation to connect to the FIX Server, everything is ok except when i tries to connect it says the field missing username. To correct this i added the following code to the toAdmin Method
void Application::toAdmin( FIX::Message& message, const FIX::SessionID& sessionID)
{
if (FIX::MsgType_Logon == message.getHeader().getField(FIX::FIELD::MsgType))
{
FIX44::Logon & logon_message = dynamic_cast<FIX44::Logon&>(message);
logon_message.setField(FIX::Username("username"));
logon_message.setField(FIX::Password("password"));
}
std::cout<<message.toString();
}
}
but is causes an exception. To check whether it is working or not also tried to print the message using std::cout<<message.ToString();
but nothing worked.
I think you were almost there. Here is my solution for initiating a FIX session with FXCM in C# (should be easy for you to port a C++ implementation).
1- Use the QuickFix Examples.TradeClient project.
2- Ensure your fix.cfg file is present in TradeClient/bin/Debug directory.
3- Ensure your dictionary (FIXFXCM10.XML) is present in TradeClient/bin/Debug directory.
4- Your main Program.cs should look something like this;
var settings = new QuickFix.SessionSettings("fix.cfg");
var client = new QuickFixClient();
var storeFactory = new QuickFix.FileStoreFactory(settings);
var logFactory = new QuickFix.ScreenLogFactory(settings);
var initiator = new QuickFix.Transport.SocketInitiator(client, storeFactory, settings, logFactory);
initiator.Start();
client.Run();
initiator.Stop();
and replace
public void ToAdmin(Message message, SessionID sessionID) {}
with this
public void ToAdmin(Message message, SessionID sessionID)
{
if (message.GetType() == typeof(QuickFix.FIX44.Logon))
{
message.SetField(new Username("YOUR_USERNAME"));
message.SetField(new Password("YOUR_PASSWORD"));
}
message.SetField(new QuickFix.Fields.Account("YOUR_ACCOUNT_NUMBER"));
}
FXCM require the account number (tag 1=) to be sent with every message to be valid. That could also prevent a successful logon if its not present.
Hope this helps!
This is how I added password:
void toAdmin( FIX::Message& message, const FIX::SessionID& sessionID)
{
// put password in the logon message
if (FIX::MsgType_Logon == message.getHeader().getField(FIX::FIELD::MsgType))
{
FIX::Password fixpasswd = ConfigSingleton::getInstance().CurrenexConfig.FIXPassword; //use your std::string password here.
message.getHeader().setField(FIX::Password(fixpasswd)); //also add username here.
}
}
If you can see your username and password, then it means ok already.
Regarding the exception, I also encountered before. For me, it comes from toApp function and I changed it as below and it works fine:
void toApp( FIX::Message& message, const FIX::SessionID& sessionID )
throw( FIX::DoNotSend )
{
try
{
FIX::PossDupFlag possDupFlag;
message.getHeader().getField( possDupFlag );
if ( possDupFlag ) throw FIX::DoNotSend();
}
catch ( FIX::FieldNotFound& e)
{
//std::cout << e.what() << " " << message.toString() << ENDLINE;
}
}
Actually, no exception.
BTW, if you didn't define your own function for some message types, the messages will be rejected.
Hope this will help.
I think my approach may be off, but this seems like a common need, so i'm hoping i'm not too far off. Any input is appreciated. When the 'publish/unpublish' button is clicked, i'd like to read 'getTask()' and take my own actions, after the core's 'publish' method completes. Here's where I start:
In the controller, in my own 'publish' method i call parent::publish. So far no problem. Then I want to read getTask and pass it to the model function.
CONTROLLER_CLASS extends jCONTROLLER_ADMIN
public function publish()
{
parent::publish();
$model = $this->getModel();
$myPublish = $this->getTask();
$model->modelVariable = $myPublish;
//or
$model->doCustomPublishWork();
}
This seemed to work out pretty well.
public function publish()
{
$publishAffliate = $this->getTask();
$cid = JRequest::getVar('cid');//affiliates DB record ID.
$fileName = "C:\wamp\bin\apache\apache2.4.2\conf\affilatesTest.txt";
$fHandle = fopen($fileName, 'a');
switch($publishAffliate)
{
case 'publish':
fwrite($fHandle, "\npublished site ID = ". $cid[0]);
break;
case 'unpublish':
fwrite($fHandle, "\nunpublished site ID = ". $cid[0]);
break;
}
parent::publish();
}