#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/*
[20:18:40]{main}z@w:/tmp
$ gcc -std=c11 src.c -o src && ./src pack 1 0 1 0 1 0
8324
[20:18:43]{main}z@w:/tmp
$ gcc -std=c11 src.c -o src && ./src unpack 8324
SignalPower=1 WorkingGroup=0 IsBlocked=1 ChargeLevel=0 HasVideoCall=1 ConnectionType=0
*/
struct __attribute__((packed)) TMobileIdentifier {
unsigned int ConnectionType : 2;
unsigned int HasVideoCall : 1;
unsigned int ChargeLevel : 3;
unsigned int Reserved6 : 1;
unsigned int IsBlocked : 1;
unsigned int Reserved8 : 1;
unsigned int WorkingGroup : 4;
unsigned int SignalPower : 3;
};
void die(const char* msg) {
}
void shift(int* argc, char*** argv) {
if (*argc == 0) {
die("no arguments left to shift");
}
(*argc)--;
(*argv)++;
}
#define $0 argv[0]
#define $1 argv[1]
#define $2 argv[2]
#define $3 argv[3]
#define $4 argv[4]
#define $5 argv[5]
void usage() {
die("Usage: packer [pack|unpack] ...args");
}
int main(int argc, char** argv) {
assert(sizeof(struct TMobileIdentifier
) <= sizeof(uint16_t) && "TMobileIdentifier doesn't fit into uint16_t"
);
if (argc == 1) {
usage();
}
shift(&argc, &argv);
shift(&argc, &argv);
if (argc != 6) {
die("Usage: packer pack SIGNAL_POWER WORKING_GROUP IS_BLOCKED CHARGE_LEVEL HAS_VIDEO_CALL CONNECTION_TYPE");
}
struct TMobileIdentifier data = {};
data.
SignalPower = atoi($
0); data.
WorkingGroup = atoi($
1); data.
IsBlocked = atoi($
2); data.
ChargeLevel = atoi($
3); data.
HasVideoCall = atoi($
4); data.
ConnectionType = atoi($
5); uint16_t encoded = 0;
memcpy(&encoded
, &data
, sizeof(data
)); } else if (!strcmp($
0, "unpack")) { shift(&argc, &argv);
if (argc != 1) {
die("Usage: packer unpack NUMBER");
}
uint16_t input
= atoi($
0); struct TMobileIdentifier decoded;
memcpy(&decoded
, &input
, sizeof(input
)); #define OUTPUT_FIELD(NAME) #NAME, decoded.NAME
fprintf(stdout
, "%s=%u\t%s=%u\t%s=%u\t%s=%u\t%s=%u\t%s=%u\n", OUTPUT_FIELD(SignalPower),
OUTPUT_FIELD(WorkingGroup),
OUTPUT_FIELD(IsBlocked),
OUTPUT_FIELD(ChargeLevel),
OUTPUT_FIELD(HasVideoCall),
OUTPUT_FIELD(ConnectionType)
);
#undef OUTPUT_FIELD
} else {
usage();
}
}
I2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW50Lmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCi8qClsyMDoxODo0MF17bWFpbn16QHc6L3RtcAokIGdjYyAtc3RkPWMxMSBzcmMuYyAtbyBzcmMgJiYgLi9zcmMgcGFjayAxIDAgMSAwIDEgMAo4MzI0ClsyMDoxODo0M117bWFpbn16QHc6L3RtcAokIGdjYyAtc3RkPWMxMSBzcmMuYyAtbyBzcmMgJiYgLi9zcmMgdW5wYWNrIDgzMjQKU2lnbmFsUG93ZXI9MSAgIFdvcmtpbmdHcm91cD0wICBJc0Jsb2NrZWQ9MSAgICAgQ2hhcmdlTGV2ZWw9MCAgIEhhc1ZpZGVvQ2FsbD0xICBDb25uZWN0aW9uVHlwZT0wCgoqLwoKc3RydWN0IF9fYXR0cmlidXRlX18oKHBhY2tlZCkpIFRNb2JpbGVJZGVudGlmaWVyIHsKCXVuc2lnbmVkIGludCBDb25uZWN0aW9uVHlwZSA6IDI7Cgl1bnNpZ25lZCBpbnQgSGFzVmlkZW9DYWxsIDogMTsKCXVuc2lnbmVkIGludCBDaGFyZ2VMZXZlbCA6IDM7Cgl1bnNpZ25lZCBpbnQgUmVzZXJ2ZWQ2IDogMTsKCXVuc2lnbmVkIGludCBJc0Jsb2NrZWQgOiAxOwoJdW5zaWduZWQgaW50IFJlc2VydmVkOCA6IDE7Cgl1bnNpZ25lZCBpbnQgV29ya2luZ0dyb3VwIDogNDsKCXVuc2lnbmVkIGludCBTaWduYWxQb3dlciA6IDM7Cn07Cgp2b2lkIGRpZShjb25zdCBjaGFyKiBtc2cpIHsKCWZwcmludGYoc3RkZXJyLCAiJXNcbiIsIG1zZyk7CglleGl0KDEpOwp9Cgp2b2lkIHNoaWZ0KGludCogYXJnYywgY2hhcioqKiBhcmd2KSB7CglpZiAoKmFyZ2MgPT0gMCkgewoJCWRpZSgibm8gYXJndW1lbnRzIGxlZnQgdG8gc2hpZnQiKTsKCX0KCSgqYXJnYyktLTsKCSgqYXJndikrKzsKfQoKI2RlZmluZSAkMCBhcmd2WzBdCiNkZWZpbmUgJDEgYXJndlsxXQojZGVmaW5lICQyIGFyZ3ZbMl0KI2RlZmluZSAkMyBhcmd2WzNdCiNkZWZpbmUgJDQgYXJndls0XQojZGVmaW5lICQ1IGFyZ3ZbNV0KCnZvaWQgdXNhZ2UoKSB7CglkaWUoIlVzYWdlOiBwYWNrZXIgW3BhY2t8dW5wYWNrXSAuLi5hcmdzIik7Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyKiogYXJndikgewoJYXNzZXJ0KHNpemVvZihzdHJ1Y3QgVE1vYmlsZUlkZW50aWZpZXIpIDw9IHNpemVvZih1aW50MTZfdCkgJiYKCQkiVE1vYmlsZUlkZW50aWZpZXIgZG9lc24ndCBmaXQgaW50byB1aW50MTZfdCIKCSk7CgoJaWYgKGFyZ2MgPT0gMSkgewoJCXVzYWdlKCk7Cgl9CglzaGlmdCgmYXJnYywgJmFyZ3YpOwoKCWlmICghc3RyY21wKCQwLCAicGFjayIpKSB7CgkJc2hpZnQoJmFyZ2MsICZhcmd2KTsKCQlpZiAoYXJnYyAhPSA2KSB7CgkJCWRpZSgiVXNhZ2U6IHBhY2tlciBwYWNrIFNJR05BTF9QT1dFUiBXT1JLSU5HX0dST1VQIElTX0JMT0NLRUQgQ0hBUkdFX0xFVkVMIEhBU19WSURFT19DQUxMIENPTk5FQ1RJT05fVFlQRSIpOwoJCX0KCQlzdHJ1Y3QgVE1vYmlsZUlkZW50aWZpZXIgZGF0YSA9IHt9OwoJCWRhdGEuU2lnbmFsUG93ZXIgPSBhdG9pKCQwKTsKCQlkYXRhLldvcmtpbmdHcm91cCA9IGF0b2koJDEpOwoJCWRhdGEuSXNCbG9ja2VkID0gYXRvaSgkMik7CgkJZGF0YS5DaGFyZ2VMZXZlbCA9IGF0b2koJDMpOwoJCWRhdGEuSGFzVmlkZW9DYWxsID0gYXRvaSgkNCk7CgkJZGF0YS5Db25uZWN0aW9uVHlwZSA9IGF0b2koJDUpOwoJCXVpbnQxNl90IGVuY29kZWQgPSAwOwoJCW1lbWNweSgmZW5jb2RlZCwgJmRhdGEsIHNpemVvZihkYXRhKSk7CgkJZnByaW50ZihzdGRvdXQsICIldVxuIiwgZW5jb2RlZCk7Cgl9IGVsc2UgaWYgKCFzdHJjbXAoJDAsICJ1bnBhY2siKSkgewoJCXNoaWZ0KCZhcmdjLCAmYXJndik7CgkJaWYgKGFyZ2MgIT0gMSkgewoJCQlkaWUoIlVzYWdlOiBwYWNrZXIgdW5wYWNrIE5VTUJFUiIpOwoJCX0KCQl1aW50MTZfdCBpbnB1dCA9IGF0b2koJDApOwoJCXN0cnVjdCBUTW9iaWxlSWRlbnRpZmllciBkZWNvZGVkOwoJCW1lbWNweSgmZGVjb2RlZCwgJmlucHV0LCBzaXplb2YoaW5wdXQpKTsKCQkjZGVmaW5lIE9VVFBVVF9GSUVMRChOQU1FKSAjTkFNRSwgZGVjb2RlZC5OQU1FCgkJZnByaW50ZihzdGRvdXQsICIlcz0ldVx0JXM9JXVcdCVzPSV1XHQlcz0ldVx0JXM9JXVcdCVzPSV1XG4iLAoJCQlPVVRQVVRfRklFTEQoU2lnbmFsUG93ZXIpLAoJCQlPVVRQVVRfRklFTEQoV29ya2luZ0dyb3VwKSwKCQkJT1VUUFVUX0ZJRUxEKElzQmxvY2tlZCksCgkJCU9VVFBVVF9GSUVMRChDaGFyZ2VMZXZlbCksCgkJCU9VVFBVVF9GSUVMRChIYXNWaWRlb0NhbGwpLAoJCQlPVVRQVVRfRklFTEQoQ29ubmVjdGlvblR5cGUpCgkJKTsKCQkjdW5kZWYgT1VUUFVUX0ZJRUxECgl9IGVsc2UgewoJCXVzYWdlKCk7Cgl9Cn0=