modify json file using cJSON library - cjson

what i want to do is reading a json format file and modify it then writing the modified content to file.
55 cJSON *root,*basicpara;
56 char *out;
57
58 root = dofile("basicparameter.cfg");
59 out = cJSON_Print(root);
60 printf("before modify:%s\n",out);
61 free(out);
62 basicpara = cJSON_GetObjectItem(root,"basicparameter");
63 cJSON_GetObjectItem(basicpara,"mode")->valueint = 0;
64 cJSON_GetObjectItem(basicpara,"TimeoutPoweron")->valueint = 10;
65
66 out = cJSON_Print(root);
67 printf("after modify:%s\n",out);
68 free(out);
69 //write_file("basicparameter.cfg",out);
70 cJSON_Delete(root);
i am confused why both contents are the same...
before modify:{
"basicparameter": {
"mode": 1,
"nBefore": 2,
"nAfter": 2,
"LuxAutoOn": 50,
"LuxAutoOff": 16,
"TimeoutPoweron": 30
}
}
after modify:{
"basicparameter": {
"mode": 1,
"nBefore": 2,
"nAfter": 2,
"LuxAutoOn": 50,
"LuxAutoOff": 16,
"TimeoutPoweron": 30
}
}

Please use the cJSON_SetNumberValue macro for setting the number. The problem is, that you are only setting the valueint property but printing relies on the valuedouble property.
Having both valueint and valuedouble in cJSON was a terrible design decision and will probably confuse many people in the future as well.

Related

Trouble writing NDEF record to NTAG213 using external NFC reader (but writing to memory works)

I am using the sample provided by Michael Roland in this answer and modified the bytes command structure to match this answer.
After I scan the tag, I receive 90 00 responses from the reader. When I then scan the tag using NFC Tools though, I don't see that it has an NDEF record (photo). If I examine the memory I can see my data written starting at block 4 as follows here.
Meanwhile, if I use the Write Tag feature of NFC Tools to write an NDEF message and then scan the tag again, it does work. The memory in the blocks other than those starting at block 4 appear to be identical (photo).
I don't believe it's a capability container issue as the memory is identical in block 3 after writing to the tag from my reader vs. NFC Tools.
Do I need to do any other kind of NDEF read / check command prior to writing to block 4?
My code below:
byte[] ndefMessage = new byte[] {
(byte)0xD1, (byte)0x01, (byte)0x0C, (byte)0x55, (byte)0x01, (byte)0x65, (byte)0x78, (byte)0x61, (byte)0x6D, (byte)0x70, (byte)0x6C, (byte)0x65, (byte)0x2E, (byte)0x63, (byte)0x6F, (byte)0x6D, (byte)0x2F
};
// wrap into TLV structure
byte[] tlvEncodedData = null;
Log.e("length",String.valueOf(ndefMessage.length));
if (ndefMessage.length < 255) {
tlvEncodedData = new byte[ndefMessage.length + 3];
tlvEncodedData[0] = (byte)0x03; // NDEF TLV tag
tlvEncodedData[1] = (byte)(ndefMessage.length & 0x0FF); // NDEF TLV length (1 byte)
System.arraycopy(ndefMessage, 0, tlvEncodedData, 2, ndefMessage.length);
tlvEncodedData[2 + ndefMessage.length] = (byte)0xFE; // Terminator TLV tag
} else {
tlvEncodedData = new byte[ndefMessage.length + 5];
tlvEncodedData[0] = (byte)0x03; // NDEF TLV tag
tlvEncodedData[1] = (byte)0xFF; // NDEF TLV length (3 byte, marker)
tlvEncodedData[2] = (byte)((ndefMessage.length >>> 8) & 0x0FF); // NDEF TLV length (3 byte, hi)
tlvEncodedData[3] = (byte)(ndefMessage.length & 0x0FF); // NDEF TLV length (3 byte, lo)
System.arraycopy(ndefMessage, 0, tlvEncodedData, 4, ndefMessage.length);
tlvEncodedData[4 + ndefMessage.length] = (byte)0xFE; // Terminator TLV tag
}
// fill up with zeros to block boundary:
tlvEncodedData = Arrays.copyOf(tlvEncodedData, (tlvEncodedData.length / 4 + 1) * 4);
for (int i = 0; i < tlvEncodedData.length; i += 4) {
byte[] command = new byte[] {
(byte)0xFF, // WRITE
(byte)0xD6,
(byte)0x00,
(byte)((4 + i / 4) & 0x0FF), // block address
(byte)0x04,
0, 0, 0, 0
};
System.arraycopy(tlvEncodedData, i, command, 5, 4);
ResponseAPDU answer = cardChannel.transmit(new CommandAPDU(command));
byte[] response = answer.getBytes();
writeLogWindow("response: "+ byteArrayToHexString(response));
}
I believe that the problem is that Michael Roland's answer has a bug in it.
D1 01 0C 55 01 65 78 61 6D 70 6C 65 2E 63 6F 6D 2F is not a valid Ndef message.
If you look at the various specs for Ndef at https://github.com/haldean/ndef/tree/master/docs (specifically the NFCForum-TS-RTD_URI_1.0.pdf and NFCForum-TS-NDEF_1.0.pdf) his example of "http://www.example.com/" is actually made up of "http://www." which has a type code of 01 and 12 characters or the rest of the URL.
Thus the payload length is 13 (1 + 12) bytes so OD where as his message:-
D1 01 0C 55 01 65 78 61 6D 70 6C 65 2E 63 6F 6D 2F
only specifies the length of the second part of the URL and not the prefix, so is one byte too short.
This is confirmed if you try and write a record for that URL using the NFC Tools App or NXP's TagWriter App both generate a message of
D1 01 0D 55 01 65 78 61 6D 70 6C 65 2E 63 6F 6D 2F
So try using in your code
byte[] ndefMessage = new byte[] {
(byte)0xD1, (byte)0x01, (byte)0x0D, (byte)0x55, (byte)0x01, (byte)0x65, (byte)0x78,
(byte)0x61, (byte)0x6D, (byte)0x70, (byte)0x6C, (byte)0x65, (byte)0x2E, (byte)0x63,
(byte)0x6F, (byte)0x6D, (byte)0x2F
};

A Very Strange phenomenon when decrypt aes-128-gcm tls package using OpenSSL in ruby

I'm implimenting my own ssl/tls library for learning purpose. These days when I seed encrypted message to server, I will a receive "bad mac" alert. Today I use this question's record to debug my code.
This is where the strange thing happend. I use his server_random, client_random and master-secret to generate client_write_key and client_write_iv. Then I get the same output as his. However, when I use the client_wrtie_key and client_write_iv to decrypt the "GET / HTTP/1.0\n" message, I get this output:
Q▒W▒ ▒7▒3▒▒▒
This is so different from the correct message! My whole debug output is
C:/Users/ayanamists/.babun/cygwin/home/ayanamists/my_ssl_in_ruby/encrypt_handler/aes_gcm_handler.rb:87:in `final': OpenSSL::Cipher::CipherError
from C:/Users/ayanamists/.babun/cygwin/home/ayanamists/my_ssl_in_ruby/encrypt_handler/aes_gcm_handler.rb:87:in `recv_decrypt'
from decrypt.rb:72:in `<main>'
client write key is
4b 11 9d fb fc 93 0a be 13 00 30 bd 53 c3 bf 78
nonce is
20 29 ca e2 c9 1d e0 05 e2 ae 50 a8
what to be decrypt:
a5 7a be e5 5c 18 36 67 b1 36 34 3f ee f4 a3 87 cb 7c f8 30 30
the tag is
a4 7e 23 0a f2 68 37 8c 4f 33 c8 b5 ba b3 d2 6d
the additional data is
00 00 00 00 00 00 00 01 17 03 03 00 00 15
decrypter is
OpenSSL::Cipher::AES
Q▒W▒ ▒7▒3▒▒▒
output is
bd 8c e8 87 b7 ab c6 f7 eb 31 fd cb 65 4c d4 a9 16 ae 1b ca da
the correct is
47 45 54 20 2f 20 48 54 54 50 2f 31 2e 30 0a
You can see that my key and nonce have no different with his key and nonce, but why the result is wrong?
The code is:
require_relative 'encrypt_message_handler'
require 'pp'
class AES_CGM_Handler
include EncryptMessageHandler
attr_accessor :send_cipher, :recv_cipher, :send_implicit, :recv_implicit,
:send_seq_num, :recv_seq_num
def initialize(server_random, client_random, certificate = '', length = 0,
usage = 'client', version_major = 0x03, version_minor = 0x03)
if block_given?
#master = yield
#version = [0x03, 0x03]
else
super(server_random, client_random, certificate)
end
# the nonce of AES_GCM is defined by:
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# + 0 1 2 3 | 0 1 2 3 4 5 6 7 +
# + salt | nonce_explicit +
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# salt is server_write_iv or client_write_iv, so you need 4 * 2
# and length need to /8(bit->byte) and * 2(both server and client), so it's length/4
key_block = (length/4 + 4 * 2).tls_prf(#master, "key expansion", server_random + client_random)
arr = key_block.unpack "a#{length/8}a#{length/8}a4a4"
client_write_key = arr[0]
server_write_key = arr[1]
client_write_iv = arr[2]
server_write_iv = arr[3]
#send_cipher = OpenSSL::Cipher::AES.new(length, :GCM).encrypt
#recv_cipher = OpenSSL::Cipher::AES.new(length, :GCM).decrypt
if usage == 'client'
#send_cipher.key = client_write_key
#send_implicit = client_write_iv
#recv_cipher.key = server_write_key
#recv_implicit = server_write_iv
puts "server write key is #{server_write_key.to_hex}"
elsif usage == 'server'
#send_cipher.key = server_write_key
#send_implicit = server_write_iv
#recv_cipher.key = client_write_key
#recv_implicit = client_write_iv
puts "client write key is\n #{client_write_key.to_hex}"
else
raise "AES_GCM_HANDLER: BAD_ARGUMENT"
end
#send_seq_num = 0
#recv_seq_num = 0
end
def send_encrypt(type = 22, seqence = '')
nonce_explicit = OpenSSL::Random.random_bytes(8)
nonce = #send_implicit + nonce_explicit
#send_cipher.iv = nonce
length = seqence.length
#the handle of seq_num may be wrong
#send_cipher.auth_data = [0, #send_seq_num,
type, #version[0], #version[1], 0 ,length].pack("NNCCCCn")
encrypt = #send_cipher.update(seqence) + #send_cipher.final
encrypt = encrypt + #send_cipher.auth_tag
return encrypt
end
def recv_decrypt(type = 22, sequence = '', seq_num = 0)
if seq_num != 0
#recv_seq_num = seq_num
end
template = 'a8a*'
arr = sequence.unpack(template)
nonce_explicit = arr[0]
length = sequence.length - 8 - 16
sequence = arr[1]
encrypted = sequence[0, sequence.length - 16]
#recv_cipher.auth_tag = sequence[sequence.length - 16, sequence.length]
#recv_cipher.iv = #recv_implicit + nonce_explicit
puts "nonce is\n #{(#recv_implicit + nonce_explicit).to_hex}"
puts "what to be decrypt: \n #{encrypted.to_hex}"
puts "the tag is \n #{sequence[sequence.length - 16, sequence.length].to_hex}"
#recv_cipher.auth_data =
[0, #recv_seq_num, type ,#version[0], #version[1], 0 ,length].pack("NNCCCCn")
puts "the additional data is\n #{([0, #recv_seq_num, type ,#version[0], #version[1], 0 ,length].pack("NNCCCCn")).to_hex }"
puts "decrypter is\n #{#recv_cipher.class}"
puts #recv_cipher.update(encrypted)
puts "output is\n #{#recv_cipher.update(encrypted).to_hex}"
puts "the correct is\n #{"GET / HTTP/1.0\n".to_hex}"
decrypt = #recv_cipher.update(encrypted) + #recv_cipher.final
return decrypt
end
end
Please help me to solve this problem, I'll be very grateful!
I have solved this question eventually!
If anyone want to use this test vector, do not forget to add "789c" as zlib compress

Gives grades according to marks

i have SSRS report i want to give "Accepted" if value between 50 and 65 and gives "Good" if value between 65 and 75 and gives "V good" if value between 75 and 85 and gives "Excellent" if value between 85 and 100
how can i do it my code :
=(IIF(Fields!marks.Value >50, "fail", 0)) And (IIF(Fields!marks.Value <65, "Accepted", 0))
You could use the Switch function to accomplish this:
=Switch(
Fields!marks.Value < 50, "fail",
Fields!marks.Value < 65, "accepted",
Fields!marks.Value < 75, "good",
Fields!marks.Value < 85, "v good",
True, "excellent"
)
what you want is a switch statement:
=switch(
Fields!marks.Value<50,"Fail",
Fields!marks.Value>= 50 and Fields!marks.Value<65,"Accepted",
Fields!marks.Value>= 65 and Fields!marks.Value<75,"Good",
Fields!marks.Value>= 75 and Fields!marks.Value<85,"V Good",
Fields!marks.Value>= 85 and Fields!marks.Value<100,"Excellent",
,"")

Is there any good and stable online SMS to PDU converter?

I'm looking for a nice online converter which could work with several modems. The problem i'm dealing with - i can't send sms in pdu mode (with Cinterion BGS-2T). Tried with my own library (still working on it) and several online converters such as:
http://www.smartposition.nl/resources/sms_pdu.html
http://m2msupport.net/m2msupport/module-tester/
http://hardisoft.ru/soft/otpravka-sms-soobshhenij-v-formate-pdu-teoriya-s-primerami-na-c-chast-1/
User data seems to be encoded well (same result everywhere), but the first part of TPDU (with PDU-Type, TP-MR, ...) may be a little bit variable (but never works, damn).
Few moments:
The modem definitely supports pdu mode.
There is cash on balance.
Modem responses on "AT+CMGS" with ">" and it responses on PDU string with "\r\nOK\r\n", but didn't responds with "+CMGS" (and of course i'm not receiving my sms).
If it necessary here is part of my own code:
void get_pdu_string(sms_descriptor* sms, char dst[]) {
char tempnum[8] = "";
char* pTemp = dst;
uint8_t i = 0;
// SMSC
//*pTemp++ = 0x00;
// PDU-Type
*pTemp++ = (0<<TP_MTIH) | (1<<TP_MTIL); // MTI = 01 - outbox sms
// TP-MR
*pTemp++ = 0x00; // unnecessary
// TP-DA
*pTemp++ = strlen(sms->to_number); // address number length
*pTemp++ = 0x91; // address number format (0x91 - international)
gsm_number_swap(sms->to_number,tempnum);
i = (((*(pTemp-2) & 0x01) == 0x01)? (*(pTemp-2)+1) : *(pTemp-2))>>1;
strncpy(pTemp, tempnum, i ); // address number
pTemp += i;
// TP-PID
*pTemp++ = 0;
// TP-DCS
switch(sms->encoding) {
case SMS_7BIT_ENC:
*pTemp++ = 0x00;
break;
case SMS_UCS2_ENC:
*pTemp++ = 0x08;
break;
}
if (sms->flash == 1)
*(pTemp-1) |= 0x10;
// TP-VP
// skip if does not need
// TP-UDL
switch(sms->encoding) {
case SMS_7BIT_ENC:
*pTemp++ = strlen(sms->msg);
break;
case SMS_UCS2_ENC:
*pTemp++ = strlen(sms->msg) << 1;
break;
}
// TP-UD
switch(sms->encoding) {
case SMS_7BIT_ENC: {
char packed_msg[140] = "";
char* pMsg = packed_msg;
gsm_7bit_enc(sms->msg, packed_msg);
while(*pMsg != 0)
*pTemp++ = *pMsg++;
} break;
case SMS_UCS2_ENC: {
wchar_t wmsg[70] = L"";
wchar_t* pMsg = wmsg;
strtoucs2(sms->msg, wmsg, METHOD_TABLE);
while(*pMsg != 0) {
*pTemp++ = (char) (*pMsg >> 8);
*pTemp++ = (char) (*pMsg++);
}
} break;
}
*pTemp = 0x1A;
return;
}
Example of my routine work:
To: 380933522620
Message: Hello! Test SMS in GSM-7
Encoded PDU string:
00 01 00 0C 81 83 90 33 25 62 02 00 00 18 C8 32 9B FD 0E 81 A8 E5 39 1D 34 6D 4E 41 69 37 E8 38 6D B6 6E 1A
Details about PDU string:
1. 00 - skipped SMSC
2. 01 - PDU-Type
3. 00 - TP-MR
4. 0C - length of To number.
5. 81 - type of number (unknown, also tried 0x91 which is international)
6. 83 90 33 25 62 02 - To number
7. 00 - TP-PID
8. 00 - TP-DCS (GSM 7bit, default SMS class)
9. 18 - TP-UD (24 letters)
10. C8 32 ... B6 6E - packed message
11. 1A - ctrl+z
Problem is fixed. I was sending message not as hex string but as binary, silly me :(
I've created balance checker for my openwrt routers. It is written in C and very simple. Works fine for velcom.by and mts.by.

can anyone help with a possible dynamic programming algorithm

Let me first apologise for the crude manner in which I am about to phrase my question. I have been refered here by a member on another site who tells me that i am looking for a dynamic programming algorithm....my question is as follows.
I am trying to sort through some data and need to find a possible sequence in the numbers
Both sets of data include the same numbers listed in different orders as in the example below.
54 47 33 58 46 38 48 37 56 52 61 25 ………………first set
54 52 33 61 38 58 37 25 48 56 47 46 ………………second set
In this example Reading from left to right the numbers 54 52 61 and 25 occur in both sets in the same order.
So other possible solutions would be…
54 52 61 25
54 33 58 46
54 33 46
54 33 38 48 56
54 48 56…. Etc.
Although this can be done by hand, I have tons of this to get through and I keep making mistakes.
Does anyone know of an existing program or script that would output all of the possible solutions?
I understand the basic structure of c++ and virtual basic programs and should be able to cobble something together in ether but to be honest I haven’t done any serious programing since the days of the zx spectrum, so please go easy on me. my main problem however is not with the program language itself but that for some reason, I am finding it impossible to catalogue the steps required in order to complete this task in English let alone in any other language.
Darcy
Sounds like you are looking for 'all common subsequences (ACS)', which is a cousin of the (more common) longest common subsequence problem (LCS).
Here's a paper discussing ACS (though they focus on just counting subsequences, not enumerating).
To come up with an algorithm you should define the desired output more precisely. For the sake of argument, say you want the set of subsequences not contained in any longer subsequence. Then one algorithm would be:
1) Apply the DP algorithm for LCS, generating the alignment/backtrack matrix
2) Backtrack all possible LCS, marking the alignment positions visited.
3) Select the largest element of the matrix not yet marked (longest remaining subsequence)
4) Backtrack, recording the sequence and marking visited alignment positions.
5) While there exists an unmarked alignment positions, goto (3)
Backtracking in your case is complicated because you will have to visit all possible paths (called "all longest common subsequences"). You can find example implementations of LCS here, which may help to get you started.
I wrote this code and it outputs the longest common sequence. It is not super optimized though, the order is O(n*m) n-> array1 size, m-> array2 size:
private void start() {
int []a = {54, 47, 33, 58, 46, 38, 48, 37, 56, 52, 61, 25};
int []b = {54, 52, 33, 61, 38, 58, 37, 25, 48, 56, 47, 46};
System.out.println(search(a,b));
}
private String search(int[] a, int[] b)
{
return search(a, b, 0, 0).toString();
}
private Vector<Integer> search(int[] a, int[] b, int s1, int s2) {
Vector<Vector<Integer>> v = new Vector<Vector<Integer>>();
for ( int i = s1; i < a.length; i++ )
{
int newS2 = find(b, a[i], s2);
if ( newS2 != -1 )
{
Vector<Integer> temp = new Vector<Integer>();
temp.add(a[i]);
Vector<Integer> others = search(a, b, i+1, newS2 + 1);
for ( int k = 0; k < others.size(); k++)
temp.add( others.get(k));
v.add(temp);
}
}
int maxSize = 0;
Vector<Integer> ret = new Vector<Integer>();
for ( int i = 0; i < v.size(); i++)
if ( v.get(i).size() > maxSize )
{
maxSize = v.get(i).size();
ret = v.get(i);
}
return ret;
}
private int find(int[] b, int elemToFind, int s2) {
for ( int j = s2; j < b.length; j++)
if ( b[j] == elemToFind)
return j;
return -1;
}

Resources