how can i store data in sim card from sim card application? - applet

i am writing a sim card applet and i need to store data on sim card.
but i didnt do it.
i found an example and use it but data disappear always when simulator restart.
i use "cmdPUTDATA(apdu);" method for save data and i use "cmdGETDATA(apdu);" method for save data.
here is my code and response;
public void process(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if (apdu.isISOInterindustryCLA()) {
if (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)) {
return;
}
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch (buffer[ISO7816.OFFSET_INS]) {
case INS_GET_BALANCE:
getBalance(apdu);
return;
case INS_CREDIT:
credit(apdu);
return;
case INS_CHARGE:
charge(apdu);
return;
// case INS_SELECT: // it is a SELECT FILE instruction
// cmdSELECT(apdu);
// break;
// case INS_VERIFY: // it is a VERIFY instruction
// cmdVERIFY(apdu);
// break;
// case INS_PUTDATA: // it is a PUT DATA instruction
// cmdPUTDATA(apdu);
// break;
// case INS_GETDATA: // it is a GET DATA instruction
// cmdGETDATA(apdu);
// break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
// #TransactionType(REQUIRED)
//synchronized
private void credit(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte numBytes = buffer[ISO7816.OFFSET_LC];
byte byteRead = (byte) (apdu.setIncomingAndReceive());
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
short creditAmount = (short) ((short) (buffer[ISO7816.OFFSET_CDATA] << (short) 8) | (buffer[ISO7816.OFFSET_CDATA + 1]));
if ((creditAmount > MAX_BALANCE) || (creditAmount < (short) 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
if ((short) (balance + creditAmount) > MAX_BALANCE) {
ISOException.throwIt(SW_MAX_BALANCE_EXCEEDED);
}
JCSystem.beginTransaction();
balance = (short) (balance + creditAmount);
JCSystem.commitTransaction();
}
private void getBalance(APDU apdu) {
byte[] buffer = apdu.getBuffer();
buffer[0] = (byte) (balance >> (short) 8);
buffer[1] = (byte) (balance & (short) 0x00FF);
//apdu.setOutgoingLength((byte) 2);
//apdu.sendBytes((short) 0, (short) 2);
apdu.setOutgoingAndSend((short)0, (short)2);
}
private void charge(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte numBytes = buffer[ISO7816.OFFSET_LC];
byte byteRead = (byte) (apdu.setIncomingAndReceive());
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
short chargeAmount = (short) ((short) (buffer[ISO7816.OFFSET_CDATA] << (short) 8) | (buffer[ISO7816.OFFSET_CDATA + 1]));
if ((chargeAmount > MAX_BALANCE) || (chargeAmount < (short) 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
if ((short) (balance - chargeAmount) < 0) {
ISOException.throwIt(SW_MIN_BALANCE_EXCEEDED);
}
JCSystem.beginTransaction();
balance = (short) (balance - chargeAmount);
JCSystem.commitTransaction();
}

When the simulator restarts? Normally Java Card simulators keep both persistent and transient memory in RAM. Use reset (requesting ATR) instead of stopping the simulator to perform a "card tear".

constructor method and my other method is here. between the "beginTransaction" and "commitTransaction" code, goto EEPROM persitent data. But it run only classic applet(java card api 3.0), it doesnt run Extendet Applet.
private Akbil_Classic(byte[] bArray, short bOffset, byte bLength) {
memory = new byte[SIZE_MEMORY];
}
private void charge(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte numBytes = buffer[ISO7816.OFFSET_LC];
byte byteRead = (byte) (apdu.setIncomingAndReceive());
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
short chargeAmount = (short) ((short) (buffer[ISO7816.OFFSET_CDATA] << (short) 8) | (buffer[ISO7816.OFFSET_CDATA + 1]));
if ((chargeAmount > MAX_BALANCE) || (chargeAmount < (short) 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
if ((short) (balance + chargeAmount) > MAX_BALANCE) {
ISOException.throwIt(SW_MAX_BALANCE_EXCEEDED);
}
JCSystem.beginTransaction();
balance = (short) (balance - chargeAmount);
JCSystem.commitTransaction();
}

Related

Socket TCP in linux - Client cannot insert username

I'm having troubles with implementing a signin/signup system with TCP/IP sockets.
So, whenever I want the user to signup, the client cannot insert the username, but he can insert the password. It looks like it is skipping one step.
Here is the code.
Client
void func(int sockfd)
{
char username[MAX], password[MAX];
int n, c;
bzero(username, sizeof(username));
printf("Enter the username : ");
n = 0;
while ((username[n++] = getchar()) != '\n')
;
write(sockfd, username, sizeof(username));
bzero(username, sizeof(username));
bzero(password, sizeof(password));
printf("Enter the password : ");
c = 0;
while ((password[c++] = getchar()) != '\n')
;
write(sockfd, password, sizeof(password));
bzero(username, sizeof(password));
}
...
int choice, ans;
func(sockfd);
bzero(buffer, 255);
n = read(sockfd, buffer, 255);
if(n < 0)
error("Error reading from socket");
printf("Server - %s", buffer);
scanf("%d", &choice);
write(sockfd, &choice, sizeof(int));
if(choice == 1) {
func(sockfd);
}
if(choice == 3) {
printf("Session terminated\n");
close(sockfd);
}
close(sockfd);
return 0;
Server
void func(int newsockfd)
{
char username[MAX], password[MAX];
int n;
bzero(username, MAX);
read(newsockfd, username, sizeof(username));
printf("From client: %s\n", username);
bzero(password, MAX);
read(newsockfd, password, sizeof(password));
printf("From client pass: %s\n", password);
while ((username[n++] = getchar()) != '\n')
;
write(newsockfd, username, sizeof(username));
}
int main(int argc, char *argv[]) {
func(newsockfd);
int num1, num2, ans, choice;
n = write(newsockfd, "Benvenuto, inserisci una scelta: \n1. Registrazione\n2. Login\n3. Esci\n", strlen("Benvenuto, inserisci una scelta: \n1. Registrazione\n2. Login\n3. Esci\n"));
if(n < 0) error("Error writing to socket");
read(newsockfd, &choice, sizeof(int));
switch(choice) {
case 1:
func(newsockfd);
break;
case 2:
break;
case 3:
close(newsockfd);
close(sockfd);
}
close(newsockfd);
close(sockfd);
return 0;
}
This is an example:
Ignoring the fact that the code provided is not complete code, the client and server are not even speaking the same protocol, so of course you are running into problems.
The client is sending the username and password to the server before it has even received the server's initial prompt.
The server is expecting the first input from the client to be the user's choice to the prompt, but the client is sending the username first, so the first few characters the server receives will be misinterpreted as an integer.
When the server does expect to receive a username and password, it sends back the username, which the client does not read.
You are also completely ignoring the return values of read() and write(). And you are not handling received strings properly, either.
With that said, try something more like this instead:
Shared
int sendAll(int sockfd, void *buf, size_t len)
{
char *pbuf = (char*) buf;
int n;
while (len > 0) {
n = send(sockfd, pbuf, len, 0);
if (n < 0) return n;
pbuf += n;
len -= n;
}
return 0;
}
int recvAll(int sockfd, void *buf, size_t len)
{
char *pbuf = (char*) buf;
int n;
while (len > 0) {
n = recv(sockfd, pbuf, len, 0);
if (n <= 0) return n;
pbuf += n;
len -= n;
}
return 1;
}
int sendInt32(int sockfd, int32_t value)
{
value = htonl(value);
return sendAll(sockfd, &value, sizeof(value));
}
int recvInt32(int sockfd, int32_t *value)
{
int n = recvAll(sockfd, value, sizeof(*value));
if (n == 1) *value = ntohl(*value);
return n;
}
int sendStr(int sockfd, const char *str)
{
int len = strlen(str);
int n = sendInt32(sockfd, len);
if (n == 0) n = sendAll(sockfd, str, len);
return n;
}
int recvStr(int sockfd, char **str)
{
*str = NULL;
int32_t len;
int n = recvInt32(sockfd, &len);
if (n <= 0) return n;
*str = malloc(len + 1);
if (*str == NULL) return -1;
n = recvAll(sockfd, *str, len);
if (n <= 0) {
free(*str);
*str = NULL;
return n;
}
(*str)[len] = '\0';
return 1;
}
Client
void func(int sockfd)
{
char input[MAX+1];
int n, c;
printf("Enter the username : ");
n = 0;
while ((n < MAX) && ((c = getchar()) != EOF) && (c != '\n')) {
input[n++] = (char) c;
}
input[n] = '\0';
if (sendStr(sockfd, input) < 0)
error("Error writing to socket");
printf("Enter the password : ");
n = 0;
while ((n < MAX) && ((c = getchar()) != EOF) && (c != '\n')) {
input[n++] = (char) c;
}
input[n] = '\0';
if (sendStr(sockfd, input) < 0)
error("Error writing to socket");
char *ans;
if (recvStr(sockfd, &ans) <= 0)
error("Error reading from socket");
printf("Server - %s: ", ans);
free(ans);
}
int main() {
int sockfd, choice;
char *str;
// connect to server...
sockfd = ...;
if (recvStr(sockfd, &str) <= 0)
error("Error reading from socket");
printf("Server - %s", str);
free(str);
scanf("%d", &choice);
if (sendInt32(sockfd, choice) < 0)
error("Error writing to socket");
switch (choice) {
case 1:
case 2:
func(sockfd);
break;
case 3:
printf("Session terminated\n");
break;
}
close(sockfd);
return 0;
}
Server
void func(int sockfd, int choice)
{
char *input;
if (recvStr(sockfd, &input) <= 0)
error("Error reading from socket");
printf("From client user: %s\n", input);
free(input);
if (recvStr(sockfd, &input) <= 0)
error("Error reading from socket");
printf("From client pass: %s\n", input);
free(input);
char *ans = (choice == 1) ? "Registered" : "Logged in";
if (sendStr(sockfd, ans) < 0)
error("Error writing to socket");
}
int main() {
int sockfd, clientsockfd, n;
int32_t choice;
// setup listening socket ...
sockfd = ...;
// accept client ...
clientsockfd = ...;
if (SendStr(clientsockfd, "Benvenuto, inserisci una scelta: \n1. Registrazione\n2. Login\n3. Esci\n") < 0)
error("Error writing to socket");
if (recvInt32(clientsockfd, &choice) < 0)
error("Error reading from socket");
switch (choice) {
case 1:
case 2:
func(clientsockfd, choice);
break;
case 3:
close(clientsockfd);
break;
}
close(sockfd);
return 0;
}
a) can you printf("choice: %d\n", choice);
b) I have problems to see if the socket is blocked by your first function call
c) most important - we have to focus on the fact, that you try to send serialized data (int) - that is totally other than sending plain text. Search google: "Network Byte Order":
//client
uint32_t choice;
choice = htons(choice);
write(sockfd, &choice, sizeof(choice));
//server
uint32_t choice;
read(newsockfd, &choice, sizeof(uint32_t));
choice = ntohs(choice);
switch(choice);

STM32 FATFS, How to proper remount SD card using SPI?

I am using a SD card for data logging. I am using the free fatfs file system from chan and SPI to communicate with the SD card. However I ran into problems when reenserting the card. It no longer works. More specifically the f_mount() function fails in in the disk_initialize() function because it is not recognized as a SDv2 card, altough it is. The first time the function is called (when booting the STM32 controller) this function returns that the card is a SDv2, after taking out the sd card, reinserting and then mounting it again it fails to detect the card.
I have tried to umount it before using f_unmount(), also I cleaned the memory of the FATFs object on the stask.
Before each write I enable powersupply to the sd card and disable it after finish of writing. This works also perfectly fine. as long as I do not reinsert the card. it seems so strange. I also tryied to reinit the SPI before each f_mount. Also does not help.
Following code works fine , but after reinserton of sd card it works no longer:
HAL_SPI_DeInit(&hspi1);
HAL_GPIO_WritePin(__SD_EN_GPIO_Port, __SD_EN_Pin, GPIO_PIN_RESET);
osDelay(10);
while(LightisIniting() == true);
/* reset physical driver */
memset(&SDFatFs, 0, sizeof(FATFS));
f_unmount("0");
osDelay(1);
/* check filenumber */
if ((errorcode = SD_Read_Filenumber()) != NO_ERROR) {
return errorcode;
}
if ((errorcode = SD_Write_Filenumber()) != NO_ERROR) {
return errorcode;
}
static uint8_t SD_Read_Filenumber()
{
char init_data[20];
uint8_t new_file_flag = 0;
uint8_t errorcode = 0;
uint16_t bytesread;
char * pEnd;
errorcode = SD_InitFATFS();
if (errorcode == NO_ERROR) errorcode = SD_File_Open(&SDFileInit, "DATA.INI", FA_OPEN_ALWAYS | FA_READ);
if (errorcode == NO_ERROR) errorcode = SD_File_Read(&SDFileInit, init_data, 20, &bytesread);
if (errorcode == ERROR_SD_READ_DATA_LEN)
{
filenumber = 0; // empty (new) data.ini-file, so set filenumber to 0
new_file_flag = 1;
errorcode = NO_ERROR;
}
else
{
if (errorcode == 0) filenumber = strtol(init_data, &pEnd, 10);
}
if (errorcode == NO_ERROR) errorcode = f_close(&SDFileInit);
if ((errorcode == NO_ERROR) && (new_file_flag)) errorcode = SD_Write_Filenumber();
if (errorcode > 0) filenumber = 0;
return errorcode;
}
static uint8_t SD_Write_Filenumber()
{
char init_data[20];
uint8_t errorcode = 0;
errorcode = SD_InitFATFS();
snprintf(init_data, 10, "%u", filenumber);
if (errorcode == NO_ERROR) errorcode = SD_File_Open(&SDFileInit, "DATA.INI", FA_CREATE_ALWAYS | FA_WRITE);
if (errorcode == NO_ERROR) errorcode = SD_File_Write(&SDFileInit, init_data, strlen(init_data));
if (errorcode == NO_ERROR) errorcode = f_close(&SDFileInit);
return errorcode;
}
int SD_Initialize() {
uint8_t errorcode = 0;
HAL_GPIO_WritePin(__SD_EN_GPIO_Port, __SD_EN_Pin, GPIO_PIN_RESET);
osDelay(1);
while(LightisIniting() == true);
/* check filenumber */
if ((errorcode = SD_Read_Filenumber()) == NO_ERROR) {
filenumber++;
if ((errorcode = SD_Write_Filenumber()) != NO_ERROR) {
return errorcode;
}
}
else {
return errorcode;
}
return 0;
}

Customize (BLUEZ) HCI LE Advertising Report format

I would like to have the ability to customize HCI LE Advertising Report so that I can gather additional Service UUIDs without connecting to an IOS app (iPhone).
The BLUEZ hcitool (via the lescan option) returns an HCI LE Advertising Report per device as follows:
Num_Reports,
Event_Type[i],
Address_Type[i],
Address[i],
Length[i],
Data[i],
RSSI[i]
My code to retrieve this HCI LE Advertising Report is based on the hcitool.c cmd_lescan functions as follows:
static void print_eir(const uint8_t *eir, uint8_t eir_len, bool le)
{
info("print_eir");
uint16_t len = 0;
if (eir_len == 0)
return;
while (len < eir_len - 1) {
uint8_t field_len = eir[0];
const uint8_t *data = &eir[2];
uint8_t data_len;
char name[239], label[100];
uint8_t flags, mask;
int i;
/* Check for the end of EIR */
if (field_len == 0)
break;
len += field_len + 1;
/* Do not continue EIR Data parsing if got incorrect length */
if (len > eir_len) {
len -= field_len + 1;
break;
}
data_len = field_len - 1;
switch (eir[1]) {
case BT_EIR_FLAGS:
info("BT_EIR_FLAGS");
flags = *data;
mask = flags;
info("Flags: 0x%2.2x", flags);
for (i = 0; eir_flags_table[i].str; i++) {
if (flags & (1 << eir_flags_table[i].bit)) {
info(" %s",
eir_flags_table[i].str);
mask &= ~(1 << eir_flags_table[i].bit);
}
}
break;
case BT_EIR_UUID16_SOME:
info("BT_EIR_UUID16_SOME\n");
if (data_len < sizeof(uint16_t))
break;
print_uuid16_list("16-bit Service UUIDs (partial)",
data, data_len);
break;
case BT_EIR_UUID16_ALL:
info("BT_EIR_UUID16_ALL\n");
if (data_len < sizeof(uint16_t))
break;
print_uuid16_list("16-bit Service UUIDs (complete)",
data, data_len);
break;
case BT_EIR_UUID32_SOME:
info("BT_EIR_UUID32_SOME\n");
if (data_len < sizeof(uint32_t))
break;
print_uuid32_list("32-bit Service UUIDs (partial)",
data, data_len);
break;
case BT_EIR_UUID32_ALL:
info("BT_EIR_UUID32_ALL\n");
if (data_len < sizeof(uint32_t))
break;
print_uuid32_list("32-bit Service UUIDs (complete)",
data, data_len);
break;
case BT_EIR_UUID128_SOME:
info("BT_EIR_UUID128_SOME\n");
if (data_len < 16)
break;
print_uuid128_list("128-bit Service UUIDs (partial)",
data, data_len);
break;
case BT_EIR_UUID128_ALL:
info("BT_EIR_UUID128_ALL\n");
if (data_len < 16)
break;
print_uuid128_list("128-bit Service UUIDs (complete)",
data, data_len);
break;
case BT_EIR_NAME_SHORT:
info("BT_EIR_NAME_SHORT");
memset(name, 0, sizeof(name));
memcpy(name, data, data_len);
info("Name (short): %s", name);
break;
case BT_EIR_NAME_COMPLETE:
info("BT_EIR_NAME_COMPLETE");
memset(name, 0, sizeof(name));
memcpy(name, data, data_len);
info("Name (complete): %s", name);
break;
case BT_EIR_SERVICE_UUID128:
info("BT_EIR_SERVICE_UUID128\n");
if (data_len < 16)
break;
print_uuid128_list("128-bit Service UUIDs",
data, data_len);
break;
case BT_EIR_SERVICE_DATA:
info("BT_EIR_SERVICE_DATA\n");
if (data_len < 2)
break;
sprintf(label, "Service Data (UUID 0x%4.4x)",
get_le16(&data[0]));
print_hex_field(label, &data[2], data_len - 2);
break;
case BT_EIR_RANDOM_ADDRESS:
info("BT_EIR_RANDOM_ADDRESS\n");
if (data_len < 6)
break;
print_addr("Random Address", data, 0x01);
break;
case BT_EIR_PUBLIC_ADDRESS:
info("BT_EIR_PUBLIC_ADDRESS\n");
if (data_len < 6)
break;
print_addr("Public Address", data, 0x00);
break;
case BT_EIR_TX_POWER:
info("BT_EIR_TX_POWER");
if (data_len < 1)
break;
info("TX power: %d dBm", (int8_t) *data);
break;
case BT_EIR_SMP_OOB_FLAGS:
info("BT_EIR_SMP_OOB_FLAGS");
info("SMP OOB Flags: 0x%2.2x", *data);
break;
default:
sprintf(label, "Unknown EIR field 0x%2.2x", eir[1]);
print_hex_field(label, data, data_len);
break;
}
eir += field_len + 1;
}
if (len < eir_len && eir[0] != 0)
packet_hexdump(eir, eir_len - len);
}
static int print_advertising_devices(int dd, uint8_t filter_type)
{
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
struct hci_filter nf, of;
struct sigaction sa;
socklen_t olen;
int len;
info("print_advertising_devices");
olen = sizeof(of);
if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0) {
error("Could not get socket options");
return -1;
}
hci_filter_clear(&nf);
hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
hci_filter_set_event(EVT_LE_META_EVENT, &nf);
if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) {
error("Could not set socket options");
return -1;
}
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_NOCLDSTOP;
sa.sa_handler = sigint_handler;
sigaction(SIGINT, &sa, NULL);
while (1) {
evt_le_meta_event *meta;
le_advertising_info *leinfo;
char btAddress[18];
while ((len = read(dd, buf, sizeof(buf))) < 0) {
if (errno == EINTR && signal_received == SIGINT) {
len = 0;
goto done;
}
if (errno == EAGAIN || errno == EINTR)
continue;
goto done;
}
ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
len -= (1 + HCI_EVENT_HDR_SIZE);
meta = (void *) ptr;
if (meta->subevent != 0x02) // must be report type
goto done;
// Overlay report structure
leinfo = (le_advertising_info *) (meta->data + 1);
// Get report count
info("************** BLE Buffer **************");
uint8_t reports_count = meta->data[0];
info("report-count: %d", reports_count);
int i; // Dump LE report data
for (i = 0; i < leinfo->length; i++) {
printf("%02x", leinfo->data[i]);
}
printf("\n");
// Get BT address & type
ba2str(&leinfo->bdaddr, btAddress);
info("BT Address: %s, Type: %s,", btAddress, (leinfo->bdaddr_type == LE_PUBLIC_ADDRESS) ? "public" : "random");
// Get BT Service name
char name[30];
memset(name, 0, sizeof(name));
eir_parse_name(leinfo->data, leinfo->length, name, sizeof(name) - 1);
info("Service name: %s", name);
// Determine Range(RSSI)
int8_t rssi;
rssi = leinfo->data[leinfo->length];
if ((uint8_t) rssi == 0x99 || rssi == 127)
error("RSSI: invalid (0x%2.2x)", (uint8_t) rssi);
else
info("RSSI: %d dBm (0x%2.2x)", rssi, (uint8_t) rssi);
print_eir(leinfo->data, leinfo->length, true);
info("****************************************");
}
done:
setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
if (len < 0)
return -1;
return 0;
}
static void cmd_lescan(int dev_id)
{
int err, dd;
uint8_t own_type = 0x01; // Random
uint8_t scan_type = 0x00; // passive scan - not sending scan responses
uint8_t filter_type = 0;
uint8_t filter_policy = 0x00;
uint16_t interval = htobs(0x0010);
uint16_t window = htobs(0x0010);
uint8_t filter_dup = 0; // not filtering duplicates
info("cmd_lescan");
if (dev_id < 0)
dev_id = hci_get_route(NULL);
dd = hci_open_dev(dev_id);
if (dd < 0) {
perror("Could not open device");
exit(1);
}
err = hci_le_set_scan_parameters(dd, scan_type, interval, window,
own_type, filter_policy, 10000);
if (err < 0) {
perror("Set scan parameters failed");
exit(1);
}
err = hci_le_set_scan_enable(dd, 0x01, filter_dup, 10000);
if (err < 0) {
perror("Enable scan failed");
exit(1);
}
info("LE Scan ...");
err = print_advertising_devices(dd, filter_type);
if (err < 0) {
perror("Could not receive advertising events");
exit(1);
}
err = hci_le_set_scan_enable(dd, 0x00, filter_dup, 10000);
if (err < 0) {
perror("Disable scan failed");
exit(1);
}
hci_close_dev(dd);
}
int main(int argc, char** argv)
{
info("main");
// flush stdout immediately
setvbuf(stdout, NULL, _IONBF, 0);
cmd_lescan(-1);
return 0;
}
I'm able to dump the HCI LE EVENT Report results for an IOS app as follows:
RAW Dump: 02011a1106111111111111111111111111111111110909434253616d706c65
************** BLE Buffer **************
report-count: 1
BT Address: 5E:96:DC:70:18:11
Type: random,
ENTER: eir_parse_name
Service name: CBSample
RSSI: -45 dBm (0xd3)
ENTER: print_eir
BT_EIR_FLAGS
Flags: 0x1a
LE General Discoverable Mode
Simultaneous LE and BR/EDR (Controller)
Simultaneous LE and BR/EDR (Host)
BT_EIR_UUID128_SOME
ENTER: print_uuid128_list
128-bit Service UUIDs (partial): 1 entry
11111111-1111-1111-1111-111111111111
BT_EIR_NAME_COMPLETE
Name (complete): CBSample
****************************************
Unfortunately, the HCI LE Adverting Report only allows for a single 128-BIT BLE Service UUID. Is there a way to customize the report to allow for further information to be gathered without connecting to a device such as iPhone(IOS)?

GZip in Blackberry 10

Hi I am new to blackberry 10 platform. I am developing an application to unzip files compressed using GZip. I am looking for extracting folder that compressed with GZip.
I have the same problem and I solved this problem by adding the following method
gUncompress(const QByteArray &data)
{
qDebug()<<"Reached Guncompress";
qDebug()<<"size="<<data.size();
if (data.size() <= 4) {
qWarning("gUncompress: Input data is truncated");
return QByteArray();
}
QByteArray result;
int ret;
z_stream strm;
static const int CHUNK_SIZE = 1024;
char out[CHUNK_SIZE];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = data.size();
strm.next_in = (Bytef*)(data.data());
ret = inflateInit2(&strm, 15 + 32); // gzip decoding
if (ret != Z_OK)
return QByteArray();
// run inflate()
do {
strm.avail_out = CHUNK_SIZE;
strm.next_out = (Bytef*)(out);
ret = inflate(&strm, Z_NO_FLUSH);
Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; // and fall through
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return QByteArray();
}
result.append(out, CHUNK_SIZE - strm.avail_out);
} while (strm.avail_out == 0);
// clean up and return
inflateEnd(&strm);
return result;
}
I think this will solve your problem

How do I use BER encoding with object System.DirectoryServices.Protocols.BerConverter.Encode("???", myData)

I need to encode and decode BER data. .NET has the class System.DirectoryServices.Protocols.BerConverter
The static method requires me to enter a string in the first parameter as shown below
byte[] oid = { 0x30, 0xD, 0x6, 0x9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0 }; // Object ID for RSA
var result2 = System.DirectoryServices.Protocols.BerConverter.Decoding("?what goes here?", oid);
BER encoding is used in LDAP, Certificates, and is commonplace in many other formats.
I'll be happy with information telling me how to Encode or Decode on this class. There is nothing on Stack Overflow or the first few pages of Google (or Bing) regarding this.
Question
How do I convert the byte array above to the corresponding OID using BER decoding?
How can I parse (or attempt to parse) SubjectPublicKeyInfo ASN.1 data in DER or BER format?
It seems the DER encoding\decoding classes are internal to the .NET framework. If so, where are they? (I'd like to ask connect.microsoft.com to make these members public)
How do I convert the byte array above to the corresponding OID using BER decoding?
After you have extracted the OID byte array, you can convert it to an OID string using OidByteArrayToString(). I have included the code below, since I couldn't find a similar function in the .NET libraries.
How can I parse (or attempt to parse) SubjectPublicKeyInfo ASN.1 data in DER or BER format?
I was not able to find a TLV parser in the .NET SDK either. Below is an implementation of a BER TLV parser, BerTlv. Since DER is a subset of BER, parsing will work the same way. Given a BER-TLV byte[] array, it will return a list of BerTlv objects that support access of sub TLVs.
It seems the DER encoding\decoding classes are internal to the .NET framework. If so, where are they? (I'd like to ask connect.microsoft.com to make these members public)
Maybe somebody else can answer this question.
Summary
Here is an example of how you can use the code provided below. I have used the public key data you provided in your previous post. The BerTlv should probably be augmented to support querying like BerTlv.getValue(rootTlvs, '/30/30/06');.
public static void Main(string[] args)
{
string pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfmJiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB";
byte[] pubkeyByteArray = Convert.FromBase64String(pubkey);
List<BerTlv> rootTlvs = BerTlv.parseTlv(pubkeyByteArray);
BerTlv firstTlv = rootTlvs.Where(tlv => tlv.Tag == 0x30).First();//first sequence (tag 30)
BerTlv secondTlv = firstTlv.SubTlv.Where(tlv => tlv.Tag == 0x30).First();//second sequence (tag 30)
BerTlv oid = secondTlv.SubTlv.Where(tlv => tlv.Tag == 0x06).First();//OID tag (tag 30)
string strOid = OidByteArrayToString(oid.Value);
Console.WriteLine(strOid);
}
Output:
1.2.840.113549.1.1.1
OID Encode/Decode
public static byte[] OidStringToByteArray(string oid)
{
string[] split = oid.Split('.');
List<byte> retVal = new List<byte>();
//root arc
if (split.Length > 0)
retVal.Add((byte)(Convert.ToInt32(split[0])*40));
//first arc
if (split.Length > 1)
retVal[0] += Convert.ToByte(split[1]);
//subsequent arcs
for (int i = 2; i < split.Length; i++)
{
int arc_value = Convert.ToInt32(split[i]);
Stack<byte> bytes = new Stack<byte>();
while (arc_value != 0)
{
byte val = (byte) ((arc_value & 0x7F) | (bytes.Count == 0 ? 0x0:0x80));
arc_value >>= 7;
bytes.Push(val);
}
retVal.AddRange(bytes);
}
return retVal.ToArray();
}
public static string OidByteArrayToString(byte[] oid)
{
StringBuilder retVal = new StringBuilder();
//first byte
if (oid.Length > 0)
retVal.Append(String.Format("{0}.{1}", oid[0] / 40, oid[0] % 40));
// subsequent bytes
int current_arc = 0;
for (int i = 1; i < oid.Length; i++)
{
current_arc = (current_arc <<= 7) | oid[i] & 0x7F;
//check if last byte of arc value
if ((oid[i] & 0x80) == 0)
{
retVal.Append('.');
retVal.Append(Convert.ToString(current_arc));
current_arc = 0;
}
}
return retVal.ToString();
}
BER-TLV Parser
class BerTlv
{
private int tag;
private int length;
private int valueOffset;
private byte[] rawData;
private List<BerTlv> subTlv;
private BerTlv(int tag, int length, int valueOffset, byte[] rawData)
{
this.tag = tag;
this.length = length;
this.valueOffset = valueOffset;
this.rawData = rawData;
this.subTlv = new List<BerTlv>();
}
public int Tag
{
get { return tag; }
}
public byte[] RawData
{
get { return rawData; }
}
public byte[] Value
{
get
{
byte[] result = new byte[length];
Array.Copy(rawData, valueOffset, result, 0, length);
return result;
}
}
public List<BerTlv> SubTlv
{
get { return subTlv; }
}
public static List<BerTlv> parseTlv(byte[] rawTlv)
{
List<BerTlv> result = new List<BerTlv>();
parseTlv(rawTlv, result);
return result;
}
private static void parseTlv(byte[] rawTlv, List<BerTlv> result)
{
for (int i = 0, start=0; i < rawTlv.Length; start=i)
{
//parse Tag
bool constructed_tlv = (rawTlv[i] & 0x20) != 0;
bool more_bytes = (rawTlv[i] & 0x1F) == 0x1F;
while (more_bytes && (rawTlv[++i] & 0x80) != 0) ;
i++;
int tag = Util.getInt(rawTlv, start, i-start);
//parse Length
bool multiByte_Length = (rawTlv[i] & 0x80) != 0;
int length = multiByte_Length ? Util.getInt(rawTlv, i+1, rawTlv[i] & 0x1F) : rawTlv[i];
i = multiByte_Length ? i + (rawTlv[i] & 0x1F) + 1: i + 1;
i += length;
byte[] rawData = new byte[i - start];
Array.Copy(rawTlv, start, rawData, 0, i - start);
BerTlv tlv = new BerTlv(tag, length, i - length, rawData);
result.Add(tlv);
if (constructed_tlv)
parseTlv(tlv.Value, tlv.subTlv);
}
}
}
Here is a utility class that contains some functions used in the class above. It is included for the sake of clarity how it works.
class Util
{
public static string getHexString(byte[] arr)
{
StringBuilder sb = new StringBuilder(arr.Length * 2);
foreach (byte b in arr)
{
sb.AppendFormat("{0:X2}", b);
}
return sb.ToString();
}
public static byte[] getBytes(String str)
{
byte[] result = new byte[str.Length >> 1];
for (int i = 0; i < result.Length; i++)
{
result[i] = (byte)Convert.ToInt32(str.Substring(i * 2, 2), 16);
}
return result;
}
public static int getInt(byte[] data, int offset, int length)
{
int result = 0;
for (int i = 0; i < length; i++)
{
result = (result << 8) | data[offset + i];
}
return result;
}
}