In this post, we will focus on writing Itevad Protocol Binary Ber Encoder. With the necessary headers and sources generated in Part_2, now we could write our Ber Encoder. Then we will run our encoder and use hexdump to see what is our Itevad msg looking like. Fire!
/* Ber encoder for Binary Itevad Protocol */ [root@localhost itevad2]# cat itevadBerEncoder.c /* Itevad Protocol Binary Ber Encoder Example http://daveti.blog.com April 1, 2012 Reference: Using the Open Source ASN.1 Compiler by Lev Walkin */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include "ItevadMessage.h" /* * This is a custom function which writes the * encoded output into some FILE stream. */ static int write_out( const void *buffer, size_t size, void *app_key) { FILE *out_fp = app_key; size_t wrote; wrote = fwrite( buffer, 1, size, out_fp); return ((wrote == size) ? 0 : -1); } int main( int ac, char **av) { /* Type to encode */ ItevadMessage_t *itevadMsg; /* Encoder return value */ asn_enc_rval_t ec; /* Allocate the ItevadMessage_t */ itevadMsg = calloc( 1, sizeof(ItevadMessage_t)); if ( !itevadMsg) { perror("calloc() failed"); exit(71); /* better, EX_OSERR */ } /* Initialize the ItevadMessage members */ /* Set version number - 1 */ itevadMsg->version = 1; /* Set IPv4 address - "1111" */ if ( OCTET_STRING_fromString( &(itevadMsg->ip4Address.address), "1111") == -1) { perror("OCTET_STRING_fromString() failed for encoding 'address'"); exit(71); } /* Set port number - 7777 */ long portNumber = 7777; itevadMsg->ip4Address.portNumber = &portNumber; /* Set the msg as a request */ itevadMsg->messageBody.present = MessageBody_PR_messageRequest; /* Set the transId - 0xffff */ long transId = 0xffff; if ( asn_long2INTEGER( &(itevadMsg->messageBody.choice.messageRequest.transactionId), transId) == -1) { perror("asn_long2INTEGER() failed for encoding 'transId'"); exit(71); } /* Set the askContent - 'who r you?' */ const char* askContent = "who r you?"; if ( OCTET_STRING_fromString( &(itevadMsg->messageBody.choice.messageRequest.askContent), askContent) == -1) { perror("OCTET_STRING_fromString() failed for encoding 'askContent'"); exit(71); } /* BER encode the data if filename is given */ if ( ac < 2) { fprintf( stderr, "Specify filename for BER outputn"); } else { /* NOTE: need memory deallocaiton before exit ! */ const char *filename = av[ 1]; FILE *fp = fopen( filename, "wb"); /* for BER output */ if ( !fp) { perror( filename); exit(71); } /* Encode the ItevadMessage type as BER (DER) */ ec = der_encode( &asn_DEF_ItevadMessage, itevadMsg, write_out, fp); fclose( fp); if ( ec.encoded == -1) { fprintf( stderr, "Could not encode ItevadMessage (at %s)n", ec.failed_type ? ec.failed_type->name : "unknown"); exit(65); /* Better, EX_DATAERR */ } else { fprintf( stderr, "Created %s with BER encoded ItevadMessagen", filename); } } /* else... */ /* Also print the constructured Itevad XER encoded (XML) */ xer_fprint( stdout, &asn_DEF_ItevadMessage, itevadMsg); /* NOTE: Need memory deallocaiton here! */ /* Encoding finished successfully */ return 0; } [root@localhost itevad2]# /* Generate and run itevadBerEncoderBin */ [root@localhost itevad2]# gcc -I. -o itevadBerEncoderBin *.c [root@localhost Itevad2]# ./itevadBerEncoderBin itevad_binary.msg Created itevad_binary.msg with BER encoded ItevadMessage <ItevadMessage> <version>1</version> <ip4Address> <address>31 31 31 31</address> <portNumber>7777</portNumber> </ip4Address> <messageBody> <messageRequest> <transactionId>65535</transactionId> <askContent>who r you?</askContent> </messageRequest> </messageBody> </ItevadMessage> [root@localhost Itevad2]# hexdump -C itevad_binary.msg 00000000 30 24 80 01 01 a1 0a 80 04 31 31 31 31 81 02 1e |0$.......1111...| 00000010 61 a2 13 a0 11 80 03 00 ff ff 81 0a 77 68 6f 20 |a...........who | 00000020 72 20 79 6f 75 3f |r you?| 00000026 [root@localhost Itevad2]# hexdump -c itevad_binary.msg 0000000 0 $ 200 001 001 241 n 200 004 1 1 1 1 201 002 036 0000010 a 242 023 240 021 200 003 377 377 201 n w h o 0000020 r y o u ? 0000026 [root@localhost itevad2]#