Ericsson Add performance Monitoring


Advertisements

MoShell Command Counter + KPI


Beberapa command dari variasi pmx dan pmr
pmx => untuk menquery nilai counter
pmxh => sama dengan pmx namun ditampilkan dalam bentuk horizontal
pmxe => untuk menquery nilai KPI based on formula yang telah di definisikan
pmxl => untuk menquerynilai counter dan di export dalam bentuk report excell
pmr => untuk menquery KPI based on Reporting yang telah di definisikan
pmrw => untuk menquery KPI based on Reporting yang telah di definisikan dan direportkan dalam bentuk web report

pmx option yang biasa digunakan adalah sebagai berikut:
-tz => menyesuaikan time zone, biasanya di indonesia +7 (-tz 7)
-m => waktu hour yang kita akan query (-m 3 artinya 3 jam akan diambil)
-h => pada dasarnya counter pmx based on rop (15 menit) kalah di option -h maka setiap 4 rop (1 jam) akan diakumulasikan
-a => aggregation semua -m akan di aggregasi menjadi satu value]
| => digunakan untuk mengambil lebih dari satu counter, bisa juga digunakan untuk cellid (rbs003w1|rbs003w2)

Berikut tips and trick penggunaan function diatas:

untuk query drop dari channel PS, URA, HS dalam waktu 2 jam
RNC> pmx cellid pmNoSystemRabReleasePacket|pmNoSystemRabReleasePacketUra|pmNoSystemRbReleaseHs -m 2 -tz 7
hasil:
Date: 2017-10-04
Object Counter 07:00 07:15 07:30 07:45 08:00 08:15 08:30 08:45
UtranCell=cellid pmNoSystemRabReleasePacket 16 7 7 6 10 12 6 11

query rejection yang ada di 3G dalam waktu 3 jam dan diaggregasikan dalam jam/hour
RNC> pmx cellid failedafteradm|pmNoRrcReqDeniedAdmDlChnlCode|pmNoRrcReqDeniedAdmDlHw|pmNoRrcReqDeniedAdmDlPwr|pmNoRrcReqDeniedAdmUlHw|pmNoOfNonHoReqDeniedHs|pmNoServingCellReqDeniedEul|pmNoOfNonHoReqDeniedEul -m 3 -tz 7 -h

Date: 2017-10-03
Object Counter 21:00 22:00 23:00
UtranCell=cellid pmNoFailedAfterAdm 3 1 2
UtranCell=cellid pmNoOfNonHoReqDeniedEul 0 0 0
UtranCell=cellid pmNoOfNonHoReqDeniedHs 0 0 0
UtranCell=cellid pmNoRrcReqDeniedAdmDlChnlCode 0 0 0
UtranCell=cellid pmNoRrcReqDeniedAdmDlHw 0 0 0
UtranCell=cellid pmNoRrcReqDeniedAdmDlPwr 0 0 0
UtranCell=cellid pmNoRrcReqDeniedAdmUlHw 0 0 0
UtranCell=cellid pmNoServingCellReqDeniedEul 0 0 0
UtranCell=cellid pmNoServingCellReqDeniedEulTti2 0 0 0

setelah contoh pmx diatas, sekarang kita mencoba untuk pmxe yang digunakan untuk mengenerate KPI:

Contoh:kita akan mengenerate accessibility dan availability dalam waktu 3 jam dan dibagi per ROP
RNC> pmxe cellid HsAccess$|SpchAccess$|EULAcces$|PSAccess$|availability$ -m 4 -tz 7
Date: 2017-10-04
Object Counter 05:00 05:15 05:30 05:45 06:00 06:15 06:30 06:45 07:00 07:15 07:30 07:45
UtranCell=cellid Availability 100 100 100 100 100 100 100 100 100 100 100 100
UtranCell=cellid HsAccess 100 98.9 99.3 100 99.7 99.4 98.0 98.2 97.5 98.6 99.3 98.4
UtranCell=cellid PSAccess 100 98.9 99.3 100 99.7 99.4 98.0 98.2 97.5 98.6 99.3 98.4
UtranCell=cellid SpchAccess N/A N/A N/A N/A 100 100 100 100 93.8 100 100 100

bagaimana dengan formula yang digunakan?, kita bisa cek di saat kita merunning command tersebut. contoh /opt/../opt/ericsson/amos/moshell/commonjars/pm/FORMULA_RNC_N_1_360.txt

didalam formula text tersebut berisi formula sbb:
HsAccess = ( 100 * pmTotNoRrcConnectReqPsSucc / ( pmTotNoRrcConnectReqPs – pmNoLoadSharingRrcConnPs ) ) * ( 100 * pmNoRabEstablishSuccessPacketInteractiveHs / pmNoRabEstablishAttemptPacketInteractiveHs ) * ( 100 * pmNoNormalNasSignReleasePs / ( pmNoNormalNasSignReleasePs + pmNoSystemNasSignReleasePs ) ) / 10000
PSAccess = ( 100 * pmTotNoRrcConnectReqPsSucc / ( pmTotNoRrcConnectReqPs – pmNoLoadSharingRrcConnPs ) ) * ( 100 * pmNoRabEstablishSuccessPacketInteractive / pmNoRabEstablishAttemptPacketInteractive ) * ( 100 * pmNoNormalNasSignReleasePs / ( pmNoNormalNasSignReleasePs + pmNoSystemNasSignReleasePs ) ) / 10000
SpchAccess = ( 100 * pmTotNoRrcConnectReqCsSucc / ( pmTotNoRrcConnectReqCs – pmNoLoadSharingRrcConnCs ) ) * ( 100 * pmNoRabEstablishSuccessSpeech / pmNoRabEstablishAttemptSpeech ) * ( 100 * pmNoNormalNasSignReleaseCs / ( pmNoNormalNasSignReleaseCs + pmNoSystemNasSignReleaseCs ) ) / 10000
Availability = 100 * ( 3600 – ( pmCellDowntimeAuto + pmCellDowntimeMan ) ) / 3600

bagaimana jika formula tersebut tidak sesuai dengan standart yang kita punya, kita bisa menggunakan formula kita sendiri dan kita simpan di folder moshell kita dan menambahkan -f lokasiformula

pmxe TTN297W HsAccessNew$|PSAccessNew$ -m 4 -tz 7 -f /home/username/ridho/FORMULA_RNC_ridh.txt

sekarang kita coba lebih advance lagi untuk menambahan script unix sort and head. case ini sangat berguna misal didalam satu RNC kita mempunyai 1000 cell, dalam kurun waktu 4 jam kita ingin mencari 10 cell mana yang memiliki masalah dalam 1 jam terakhir. Script ini sangat berguna untuk contoh pmNoFailedAfterAdm memiliki nilai besar biasanya ada transport issue
sort => untuk nge-sort dari nilai terbesar sampai terkecil atau sebaliknya
head => untuk mengambil top n line
contoh:
kita ingin mengambil 15 contributor cell yang memiliki failafteradm yang tinggi di 1 jam terakhir tambahkan script berikut
=> (sort -k6 -n -r => untuk meng-sort dari kolom keenam)
=> (head -15 ==> untuk mengambil 15 top)
RNC> pmx UtranCell=.* failedafteradm -m 4 -tz 7 -h | sort -k6 -n -r | head -15

Report from 2017-10-03 22:15 UTC to 2017-10-04 02:14 UTC (16 ropfiles)
Node SW: CXP9021776/4_R4YB04 (W15B)
UtranCell=XXX042W2 pmNoFailedAfterAdm 78 41 9 26 34
UtranCell=XXX304W1 pmNoFailedAfterAdm 0 1 3 44 33
UtranCell=XXX885W3 pmNoFailedAfterAdm 5 29 28 83 20
UtranCell=XXX967W1 pmNoFailedAfterAdm 13 39 37 66 16
UtranCell=XXX702W2 pmNoFailedAfterAdm 3 7 14 36 15
UtranCell=XXX351W1 pmNoFailedAfterAdm 0 2 2 6 14
UtranCell=XXX311W6 pmNoFailedAfterAdm 6 6 14 48 14
UtranCell=XXX508MA2 pmNoFailedAfterAdm 3 23 25 25 14
UtranCell=XXX042W5 pmNoFailedAfterAdm 11 16 6 19 14
UtranCell=XXX002W9 pmNoFailedAfterAdm 1 2 5 10 14
UtranCell=XXX516MA2 pmNoFailedAfterAdm 2 10 22 30 13
UtranCell=XXX365W3 pmNoFailedAfterAdm 13 23 26 38 11
UtranCell=XXX933W3 pmNoFailedAfterAdm 4 20 9 9 11
UtranCell=XXX730MA2 pmNoFailedAfterAdm 2 5 14 12 11
UtranCell=XXX508MA1 pmNoFailedAfterAdm 20 54 29 69 11

Note: untuk sort dan head diatas, masih belum ketemu cara exclude time ROP nya agar ngak ikut di sort, tetapi tidak merubah result analisa secara keseluruhan

kita coba satu case lagi untuk pmx, misal kita ingin mencari NodeB yang flicker, flicker ya bukan down. counter yang kita pakai pmCellDowntimeAuto yang menunjukan nodeB outage yang bukan di locked. Jika nodeB itu outage full 1 jam (60 menit) maka pmCellDowntimeAuto akan bernilai 3600 (pmCellDowntimeAuto satuannya second). jadi kita ingin menexclude node B yang down selama 1 jam dan menampilkan RBS yang memiliki downtime flicker. Script ini sangat berguna untuk memonitor nodeB yang flicker due to Transport problem
RNC> pmx . pmCellDowntimeAuto -m 12 -tz 7 -h | sed -e ‘s/3600/Mati/g’ | sort -rk14 | head -40 | grep -v “Mati”

Object Counter 00:00 01:00 02:00 03:00 04:00 05:00 06:00 07:00 08:00 09:00 10:00 11:00 12:00
UtranCell=XXX516W9 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W8 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W7 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W6 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W5 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W4 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W3 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W2 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX516W1 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1558 1090 0
UtranCell=XXX506W9 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W8 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W7 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W6 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W5 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W4 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W3 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W2 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX506W1 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 0 0 1556 863 0
UtranCell=XXX605W9 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 1632 0 1558 859 0
UtranCell=XXX605W8 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 1632 0 1558 859 0
UtranCell=XXX605W7 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 1632 0 1558 859 0
UtranCell=XXX605W6 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 1632 0 1558 859 0
UtranCell=XXX605W5 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 1632 0 1558 859 0
UtranCell=XXX605W4 pmCellDowntimeAuto 0 0 0 0 0 0 0 0 1632 0 1558 859 0

Berkikut beberapa script yang mungkin berguna khusus nya untuk monitoring performance

//query contributor rejection due to, sort and head
RNC> pmxe UtranCell=.* DlConnLimit$|DlAse$|DlChnlCode$|DlHw$|DlHwBest$|DDlPwr$ -m 6 -tz 7 -h | sort -nrk9 | head -40
//query contributor fail due to, sort and head
RNC> pmxe UtranCell=.* Fail$ -m 6 -tz 7 -h | sort -nrk9 | head -40
//query KPI accessability, sort and head
RNC> pmxe UtranCell=.* HsAccess$|EULAcces$|PSAccess$ -m 6 -tz 7 -h | sort -k9 | head -40
//query KPI Drop, sort and head
RNC> pmxe UtranCell=.* CS64Drop$|SpchDrop$|CS57Drop$|PSDrop$|HsDrop$ -m 6 -tz 7 -h | sort -rk8 | head -40
//query afteradm, sort and head
RNC> pmx UtranCell=.* failedafteradm -m 4 -tz 7 | sort -k17 -n -r | head -15
//query Rejection license EUL, sort and head
RNC> pmx UtranCell=.* pmNoOfNonHoReqDeniedEul -m 4 -tz 7 | sort -k18 -n -r |head -30
//query Rejection Code, HW, Pwr, License HS, sort and head
RNC> pmx UtranCell=.* pmNoRrcReqDeniedAdmDlChnlCode|pmNoRrcReqDeniedAdmDlHw|pmNoRrcReqDeniedAdmDlPwr|pmNoRrcReqDeniedAdmUlHw|pmNoOfNonHoReqDeniedHs -m 4 -tz 7 | sort -k18 -n -r |head -30
//query RBS Flicker
RNC> pmx . pmCellDowntimeAuto -m 12 -tz 7 -h | sed -e ‘s/3600/Mati/g’ | sort -rk14 | head -40 | grep -v “Mati”
//ini buat liat attempt hand over
RNC> pmxh UtranCell pmrladd.*bestcellspeec -m 48 -tz 7 -a
//query speech drop
RNC> pmx cellid pmNoSysRelSpeechNeighbr|pmNoSystemRabReleaseSpeech -m 4 -tz 7

//check frame lost
RBS> pmxl . pmHsData -m 48 -tz 7
RBS> pmx . pmHsData -m 4 -tz 7

Untuk yang pmr dan yg 4G, next kita bahas kembali

MoShell Command (Troubleshooting)


Berikut Moshell Command yang biasa digunakan untuk troubleshooting RBS Ericsson

Site3G> lt all (load all)
Site3G> alt (cek alarm)
Site3G> lge
Site3G> lga 1d (alarm 1hari)
Site3G> lgo (perubahan database)
Site3G> lgn (perubahan database & user)
Site3G> cabx (cek RBS)
Site3G> invhl (cek inventory)
Site3G> cvls (cek activity RBS)
Site3G> cvms ….. (create CV)
Site3G> lst host
Site3G> lst carr
Site3G> lst iub
Site3G> get . antennasupervision (cek antena supervise)
Site3G> set . antennaSupervisionThreshold 80

cek TA/ TP (Timing Advance)
Site3G> pmx prach pmpropagationdelay -m 48 -a
Site3G> pmx . pmPrachPropagationDelay -m 48 -a ==> ngecek prach di base band 3G

Site3G> hget radio no –> cek traffic
Site3G> st ru –> cek status RU
Site3G> pmr –> cek RSSI
Site3G> hget sector long|lat –>cek longlat
Site3G> get node chann

Site3G> get . txmaxdl
Site3G> get . maxdl
Site3G> get . maxtot (cek maxTotalOutputPower)
Site3G> set . maxTotalOutputPower 80
Site3G> get . maxtot
Site3G> st plugin –> cek status RU/cari proxy brp yg mau direstart
Site3G> acl (proxy)80 (restart per modul)
Site3G> acc 80 manualrestart -> y ->2 (coldrestart) ->6 ->0

Site3G> st plug
Site3G> acl 189
Site3G> acc 189 restartAuxUnit (reset RU)
Site3G> y

cek konfigurasi DUW/RRU
Site3G> get . dbcc

restart RBS
================
Site3G> acc 0 manualrestart
Site3G> y
Site3G> 3
Site3G> 6
Site3G> 0
Site3G> lt all

restart restartAuxUnit
Site3G> acl (proxy)
Site3G> acc (proxy) restartAuxUnit -> y

Site3G> st plug
Site3G> acl 357
Site3G> acc 357 restartauxunit -> y

Menghitung Troughput GSM, GPRS , EDGE/EGPRS, EDGE2/EGPRS2


Throughput = (Simbol dalam 1 time slot)/(waktu 1 frame) x (jumlah frame untuk data)/(jumlah frame total)

GSM
Throughput Voice full rate GSM = (114 / 4.615 ms) x (24/26) = 22.8 kbps

GPRS
Throughput GPRS = (912 / 4.615) x (24/26) = 182.4 kbps

EDGE/EGPRS
Throughput EDGE = (912 / 4.615) x (24/26) x 3 = 547.2 kbps

EDGE2/EGPRS2
Throughput EDGE2 = (1088 / 4.615) x (24/26) = 217.6 kbps
Throughput EDGE2 (32 QAM) = (1088 / 4.615) x (24/26) x 5 = 1.08 mbps

Merubah dari Bytes ke Bentuk Hexadecimal & Contoh Enkripsi simple menggunakan algoritma simetrik


Enkripsi menggunakan JCE-JCA baik menggunakan provider bawaan java ataupun provider lain seperti BC mempunyai inputan, outputan dan kunci beupa array byte sesuai dengan panjang dari spesifikasi algoritma tersebut. Untuk memudahkan verifikasi hasil khususnya didalam console print kita dapat menggunakan format hexadecimal sebagai representasi dari data array byte, sebagai contoh berikut:

byte[] input = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

data diatas jika kita langsung System.out.println(input); maka hasil yang kita dapatkan adalah [B@372ea2bc, tidak sesuai dengan reperesentasi byte yang kita inginkan oleh karena itu diperlukan fungsi sebagai berikut

public class Utils
{
    private static String digits = "0123456789abcdef";
    /**
     * Return length many bytes of the passed in byte array as a hex string.
     *
     * @param data the bytes to be converted.
     * @param length the number of bytes in the data block to be converted.
     * @return a hex representation of length bytes of data.
     */
    public static String toHex(byte[] data, int length)
    {
        StringBuffer    buf = new StringBuffer();
        for (int i = 0; i != length; i++)
        {
            int v = data[i] & 0xff;
            buf.append(digits.charAt(v >> 4));
            buf.append(digits.charAt(v & 0xf));
        }
        return buf.toString();
    }
    /**
     * Return the passed in byte array as a hex string.
     *
     * @param data the bytes to be converted.
     * @return a hex representation of data.
     */
    public static String toHex(byte[] data)
    {
        return toHex(data, data.length);
    }
}

sebagai contoh, fungsi tersebut kita gunakan untuk Enkirpsi menggunakan AES dengan mode ECB dan tanpa padding, sebagai berikut:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class SimpleSymmetricExample
{
    public static void main(String[] args) throws Exception
    {
        byte[]        input = new byte[] {
                          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                          (byte)0x88, (byte)0x99, (byte)0xaa, (byte)0xbb,
                          (byte)0xcc, (byte)0xdd, (byte)0xee, (byte)0xff };
        byte[]        keyBytes = new byte[] {
                          0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        Cipher        cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
        System.out.println("input text : " + Utils.toHex(input));
        // encryption pass
        byte[] cipherText = new byte[input.length];
        cipher.init(Cipher.ENCRYPT_MODE, key);
        int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
        ctLength += cipher.doFinal(cipherText, ctLength);
        System.out.println("cipher text: " + Utils.toHex(cipherText)
                                                     + " bytes: " + ctLength);

        // decryption pass
        byte[] plainText = new byte[ctLength];
        cipher.init(Cipher.DECRYPT_MODE, key);
        int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
        ptLength += cipher.doFinal(plainText, ptLength);
        System.out.println("plain text : " + Utils.toHex(plainText)
                                                     + " bytes: " + ptLength);
    }
}

maka hasil yang kita dapatkan sebagai berikut:
input text : 00112233445566778899aabbccddeeff
cipher text: dda97ca4864cdfe06eaf70a0ec0d7191 bytes: 16
plain text : 00112233445566778899aabbccddeeff bytes: 16

Mengirim multiple Email menggunakan SSL Java


Kali ini misal kita dihadapkan case sebagai berikut:
– Kirimkan email berikut gambar dan attachment ke 20 list penerima
– email harus bersifat personal atau tanpa menggabung alamat-alamat email tersebut kedalam satu surat
– Judul disisipkan Nama penerima , dan juga format message disisipkan nama lengkap dan nama panggilan
– format message yang dimaksud sebagai berikut:

Continue reading “Mengirim multiple Email menggunakan SSL Java”

Install provider Bouncy castle


Sebenarnya kita dapat menggunakan library bawaan java yaoti JCA dan JCE, namun kali ini kita menggunakan provider lain yaitu Bouncy castle, BC sendiri adalah salah satu komunitas open source yang memiliki interest kebidang kirptografi sejak tahun 1990 khususnya didalam pemograman c# dan java. BC sendiri sudah mendukung algoritma kriptografi simetrik seperti GOST. Untuk menginstall dan menEnableKan berikut langkah-langkahnya

tambahkan didalam line berikut list provider java.security didirektori /usr/lib/jvm/java-8-oracle/jre/lib/security

security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider

N adalah urutan sesuai nomor urut yang terdapat didalam java.security anda, sebagai contoh

#
# List of providers and their preference orders (see above):
#
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC

maka tambahkandilne setelah N=9: security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

setelah itu install library bcprov-JdkVersion-Version.jar. sesuai versi yang anda inginkan, .jar dapat didownload di https://www.bouncycastle.org/latest_releases.html

cek apakah BC sudah terinstall:


import java.security.Security;
/**
* Basic class to confirm the Bouncy Castle provider is
* installed.
*/
public class SimpleProviderTest
{
public static void main(String[] args)
{
String providerName = "BC";
if (Security.getProvider(providerName) == null)
{
System.out.println(providerName + " provider not installed");
}
else
{
System.out.println(providerName + " is installed.");
}
}
}

Jika sudah di console akan terprint
BC is installed.

Continue reading “Install provider Bouncy castle”