I am using this line to send a message via a Ruby (1.8.7) socket:
##socket.send login_message, 0
(This works fine)
What is the second parameter for? I can't find the send method in the Ruby API docs...
I first thought that it was some C style length of the message. This is why I used login_message.length as second parameter. That worked but I encountered a strange behavior:
Everything works fine when the second parameter is a odd number. If it's an even number the last character gets lost at receiving on the other side (The other side is a C++ program with a C socket). I inspected the network traffic with Wireshark and noticed that the packets look good. All the data is complete. Why is the last character lost when I receive it?
Thank you
Lennart
This is the flags parameter, the same as the last parameter to the send() system call. Normally it should be 0, but may be something like Socket::MSG_OOB (to send out-of-band data). For Ruby 1.9 this is documented under BasicSocket.
Related
SGP.02 - Remote Provisioning Architecture for Embedded UICC Technical Specification (page 255 of v4.0 specifically) says:
the data format provided by the function caller SHALL NOT depend of the selected OTA protocol capabilities (for example SM-DP can consider there is no limit on data length)
and later
The SM-SR has the responsibility to build the final Command script,
depending on eUICC capabilities and selected protocol:
by adding the Command scripting template for definite or indefinite length,
and, if necessary, by segmenting the provided command script into several pieces
and, if necessary, by adding the relevant Script Chaining TLVs.
I understand it that SM-DP can send arbitrary long data parameter to ES3.SendData and SM-SR should send several APDUs in multiple SMSes if data is too large to fit into one. And that is meant by segmenting.
The problem is I can't find a relevant specification that defines how segmenting should be done. And that's the question: where is the segmenting process defined?
I may be wrong but it seems that is not the same as Concatenated Short Messages described in the section 6.3 of ETSI TS 123 048.
It seems that Script Chaining briefly mentioned in ETSI TS 102 226 is somewhat related so pointers to the specification that defines how it works are also very much welcome (TS 102 226 talks about Script Chaining TLVs but not how to use them, at least I'm definitely missing some broader context how it works so any hints are appreciated).
UPDATE:
ES8.EstablishISDPKeySet function requires 3 APDUs to be sent. And they are quite big as they contain keys. From SGP.02-v4.0 table 150 I understand it that they are sent from SM-DP to SM-SR using Expanded Remote Command Format. The script in this format can be rather large as far as I understand (given that SM-DP can assume that there is no limitation on the data length). And it is not clear how SM-SR should segment it or use chaining. I'm just missing the specs where this is described.
The eUICC has a limited internal buffer, i.e. it cannot store a complete profile package of 10kb or more internally. The message must be chunked. If the eUICC supports just e.g. 1 kb then you have to split the APDU commands after at most 3 APDU commands to stay below 1kb. The SGP.02 specification defines to have at least 1024 bytes. A fully featured SM-SR might store some attributes based on the eUICC vendor in the EID to add special handling and patches for certain eUICCs to support a larger buffer size.
Encode each APDUs chunk (1..n APDUs) into the Expanded Remote Command Format (ETSI TS 102 226, sect. 5.2.1) (compact format can only have one response for the last APDU, but if it works, you could save a few bytes)
Encode each Expanded Remote Commands message into a SMS-DELIVER (TS 123 048 and simalliance Interoperability Stepping Stones release 6) This includes the data encryption using the OTA keys (KiC, KID). gsm0348 is a good Java library for this. Pay attention: For each message the OTA counter must be incremented. Select one reference number and keep it for all messages. I guess this is the identifier how the eUICC knows which messages belong together.
If using SMS (I would suggest to use CAT-TP or HTTPs instead -> faster and more reliable) encode it as SMS-PP Download message (TS 131 111). You will using message concatenation here if the payload is more than 140 bytes.
You will receive as response a SendShortMessage (TS 131 111, 6.4.10). Extract the user data again with TS 123 048 and simalliance Interoperability Stepping Stones release 6. You get the SMS Response message. Look into the response packet to get the user data.
Extract the user data as Expanded Remote Response (ETSI TS 102 226)
The eUICC will handle the streamed messages. The concatenated short messages are only used for a message chunk belonging together during the transit.
The best specification that kind of explains how segmenting and script chaining works in details is SGP.11 Remote Provisioning Architecture for Embedded UICC Test Specification.
It does not have a requirements per se but it has the byte level examples of incoming ES3.SendData and examples of the messages received by eUICC. And this allows to deduce the actual behaviour of the SM-SR pretty easily.
And here is more detailed explanation with references to that specification.
Command script
Command script is a list of commands sent in the data fields of the ES3.SendData. It can be (see data field description in table 150 of SGP.02-v4.0) either:
the list of C-APDUs commands (defined in EXPANDED_COMMANDS method on page 595 of SGP.11-v4.0 and uses in step 2 on page 407 of SGP.11-v4.0)
TLV commands that form a SCP03t script (defined in SCP03T_SCRIPT method on page 600 of SGP.11-v4.0 and used in step 14 on page 408 of SGP.11-v4.0)
Script Chaining
Script chaining is the feature used when there is a need to execute several commands sent in multiple transport messages but when some context of the execution needs to preserved after the first command is executed and used for the next one (for example the first command is INSTALL [for personalization] and the second one is STORE DATA). This context is command session defined in section 4 of TS 102 226.
This is used at least in these cases (which is also supported by Annex K in SGP.02):
when the followup command is based on the response from eUICC
when command script is too large and cannot be sent in one piece
Script chaining is performed by SM-SR and is implemented by adding Script Chaining TLV to the command script in Expanded Remote format. See section 5.4.1.2 in TS 102 226.
Examples of script chaining can be found in SGP.11-v4.0.
For the first case see the scenario for EstablishISDRKeyset procedure in section 4.2.10.2.1.1 . For the second case see the scenario for DownloadAndInstallation procedure in section 4.2.18.2.1.1. The byte level representation of the script chaining is described in SCP80_PACKET method on page 601 (see option CHAINING_OPT).
It seems that explicit chaining is applicable only to SMS or CAT_TP transport. For HTTPS the command session coincides with the administrative session as defined in section 3.6 of Remote Application Management over HTTP – Public Release v1.1.3 so there is not need to add explicit Script Chaining TLVs.
Segmenting
When the command script is too large and cannot be sent in one piece SMSR generates multiple command scripts. The commands that SMSR received from SMDP CMD1, CMD2, …, CMDN (see step 14 on page 408 of SGP.11-v4.0) and that form a command script are split into several command scripts. The first one contains some initial portion of the commands CMD1, CMD2, …, CMDi. The second command script contains commands CMDi+1, CMDi+2, …, CMDj. The third one CMDj+1,…,CMDk and so on.
If SMS or CAT_TP is used then for every command a Chaining TLV is added to the beginning with the appropriate value (see section 4.2.18.2.1.1 in SGP.11-v4.0).
And then every new command script is sent in a separate message to eUICC.
I'm sure most Windows developers are familiar with this error message, usually when trying to mix 32- and 64-bit executables. In particular Python and Java can both get it.
%1 is not a valid Win32 application.
It's clear that %1 represents the first argument to the failing command - i.e. the executable that is trying to be loaded - but why does it not get filled in with the actual path?
Is it something that the caller is doing wrong, or is it a basic failing of some Windows subsystem that cannot be fixed for compatibility reasons?
The error message comes from Windows itself, you can see the complete list at System Error Codes (0-499). You translate an error code returned by the API into a message using FormatMessage, which has an optional Arguments array; any %1 in the message will be replaced by the first element in this array. If nothing is passed for the arguments, the %1 will be left unchanged if the FORMAT_MESSAGE_IGNORE_INSERTS flag was used or the FormatMessage will fail if it wasn't (thanks to IInspectable for that information).
As an example of how this might get missed, consider code where an error code gets converted immediately to an exception. If the exception contains the error code but nothing else, then there is no context for knowing what to pass to FormatMessage.
The caller is doing everything right. They are calling FormatMessage, passing along the FORMAT_MESSAGE_IGNORE_INSERTS flag1), like everyone should. The caller is not in control of the message that gets created, and has no way of knowing, that it should pass additional arguments, what types they should be or how many.
This was an early design bug in the Windows error reporting system, and you'll see those placeholders in every well-behaved application.
1) See The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag.
I am currently doing the Ruby on the Web project for The Odin Project. The goal is to implement a very basic webserver that parses and responds to GET or POST requests.
My solution uses IO#gets and IO#read(maxlen) together with the Content-Length Header attribute to do the parsing.
Other solution use IO#read_nonblock. I googled for it, but was quite confused with the documentation for it. It's often mentioned together with Kernel#select, which didn't really help either.
Can someone explain to me what the nonblock calls do differently than the normal ones, how they avoid blocking the thread of execution, and how they play together with the Kernel#select method?
explain to me what the nonblock calls do differently than the normal ones
The crucial difference in behavior is when there is no data available to read at call time, but not at EOF:
read_nonblock() raises an exception kind of IO::WaitReadable
normal read(length) waits until length bytes are read (or EOF)
how they avoid blocking the thread of execution
According to the documentation, #read_nonblock is using the read(2) system call after O_NONBLOCK is set for the underlying file descriptor.
how they play together with the Kernel#select method?
There's also IO.select. We can use it in this case to wait for availability of input data, so that a subsequent read_nonblock() won't cause an error. This is especially useful if there are multiple input streams, where it is not known from which stream data will arrive next and for which read() would have to be called.
In a blocking write you wait until bytes got written to a file, on the other hand a nonblocking write exits immediately. It means, that you can continue to execute your program, while operating system asynchronously writes data to a file. Then, when you want to write again, you use select to see whether the file is ready to accept next write.
I would like to print out the actual line in Ruby for demonstrative purposes to demonstrate the working of a Ruby CGI application: it would send the actual line by an AJAX call response to a webpage, and then simply wait a few seconds or for some user action.
I know there is a __LINE__ variable, which contains the actual line number. I would like to install a signal trap, "variable watch" or other similar interrupt mechanism which is always called when __LINE__ is changing, or if there is any dedicated interrupt which is always called and can be registered for this purpose. How can I achieve this?
Have you tried http://ruby-doc.org/core-2.2.3/Kernel.html#method-i-caller ?
With this, you scan call trace and find first related file, then extract line number with something like /\d+(?=:in)/
I have written a simple program that goes like this ..
#include<stdio.h>
int main()
{
int i=0;
while(1)
printf("......%d...\n",i++);
return 0;
}
When this process will run under windows, it will act like a client and the server will be Csrss.exe. Now my question is that when this client will try to print something it will send a request to the server, and the further process about printing is done by the server(Csrss.exe).But what would happen with the client? the client process will continue executing without bothering about whether the value actually get printed or not? or the server will block the client until it get some notification from system space ??
If you are going with the second solution then please also explain that in MSDN it is written that after using CreateProcess() we should use WaitForInputIdle() API to make sure that the object is actually created in the system space. So what I can get from this statement is that server will not block the client after making a request ..
and if you are going with the first solution then the output of the program is correct, i mean not a single value of i got missed ??
Basically, your process' standard output is a pipe to csrss.exe. printf writes to that pipe. It would block at least until the data is stored in some system buffer. Whether it blocks all the way until the server reads the text from the pipe and renders it on the screen, I'm not sure, and I don't quite see why it would matter.
WaitForInputIdle is only significant for windowed applications, not for console ones. It waits until the target process calls GetMessage or similar for the first time. Console processes don't typically do that. From the documentation: "If this process is a console application ..., WaitForInputIdle returns immediately."
I don't understand your concern about "missed values".