Guest User

FM transmitter frequency set tool for Raspberry Pi

a guest
Dec 21st, 2012
548
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Raspberry Pi frequency set tool for the B-Link / Keene FM transmitter
  2. // Original source from: https://github.com/kenchy/keene-usb-audio
  3. // To compile: gcc -o fmtx fmtx.c -lusb
  4. // If you're missing usb.h make sure libusb-dev is installed
  5. // Due to low level USB access it must run from as root or via sudo
  6. //
  7. // source code modifications by redhawk 20/12/2012:
  8. // fixed - "Segmentation fault" due to out of range frequency (usb handle closed wasn't actually opened)
  9. // added - set frequency with decimal value
  10. // added - option to power off transmitter
  11. // added - stereo / mono selection
  12. // added - 50us / 75us pre-emphasis selection
  13. // added - transmission power adjustment
  14. // added - TX volume control
  15. // added - DSP volume control (via aplay and amixer)
  16. // changed - error and help messages
  17. // changed - lowered TX volume this helped to reduce background noise from PI USB power supply
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <usb.h>
  22. #include <errno.h>
  23.  
  24. extern int errnol;
  25. usb_dev_handle  *keenehandle;
  26.  
  27. #define keeneVID  0x046d
  28. #define keenePID  0x0a0e
  29. #define tx_min_freq 8750  // Minimum frequency: Japan = 7600, USA = 8810,  UK/EU = 8750
  30. #define tx_max_freq 10800 // Maximum frequency: Japan = 9000, USA = 10790, UK/EU = 10800
  31. #define tx_off_freq 11400 // Out of range frequency will actual turn off the Transmitter
  32.  
  33. // ** cleanup() *****************************************************
  34. void cleanup() {
  35.     usb_set_debug(0);
  36.     // if we have the USB device, hand it back
  37.     if (keenehandle) {
  38.         usb_release_interface(keenehandle,2);
  39.         usb_close(keenehandle);
  40.     }
  41.     exit(errno);
  42. }
  43.  
  44. void set_dsp(int volume_level) {
  45.   FILE *fp;
  46.   char output[2];
  47.   char *cmd;
  48.   int card_no = -1;
  49.   int vol = volume_level;
  50.   fp = popen("aplay -l | fgrep -i B-Link | awk '{ print substr($2,1,1) }'","r");
  51.   fgets(output, sizeof output, fp);
  52.   if (strcmp(output, "0") == 0) { card_no = 0; }
  53.   if (atoi(output) > 0) { card_no = atoi(output); }
  54.   pclose(fp);
  55.   if (card_no == -1) {
  56.     printf("Error: B-Link audio DSP not found\n");
  57.     exit(1);
  58.   }
  59.   if (vol > 56) { vol = 56; }
  60.   if (vol < 0) { vol = 0; }
  61.   char str_vol[2];
  62.   sprintf(str_vol, "%d", vol);
  63.   strcpy(cmd,"amixer -c");
  64.   strcat(cmd, output);
  65.   strcat(cmd, " set PCM ");
  66.   strcat(cmd, str_vol);
  67.   strcat(cmd, " >/dev/null");
  68.   system(cmd);
  69.   exit(0);
  70. }
  71.  
  72. usb_dev_handle * GetFirstDevice(int vendorid, int productid) {
  73.   struct usb_bus    *bus;
  74.   struct usb_device *dev;
  75.  
  76.   usb_dev_handle    *device_handle = NULL; // it's a null
  77.  
  78.   usb_init();
  79.   usb_set_debug(0);     /* 3 is the max setting */
  80.  
  81.   usb_find_busses();
  82.   usb_find_devices();
  83.  
  84.   // Loop through each bus and device until you find the first match
  85.   // open it and return it's usb device handle
  86.  
  87.   for (bus = usb_busses; bus; bus = bus->next) {
  88.     for (dev = bus->devices; dev; dev = dev->next) {
  89.       //if (dev->descriptor.idVendor == vendorid && dev->descriptor.idProduct == productid) {
  90.       if (dev->descriptor.idVendor == vendorid) {
  91.     device_handle = usb_open(dev);
  92.     //
  93.     // No device found
  94.     if(!device_handle) {
  95.       return NULL;
  96.     }
  97. //    fprintf(stderr," + Found audio transmiter on bus %s dev %s\n", dev->bus->dirname, dev->filename);
  98.     return (device_handle);
  99.       }
  100.     }
  101.   }
  102.   errno = ENOENT;       // No such device
  103.   return (device_handle);
  104. }
  105.  
  106. int help(char *prog, int more_options) {
  107.  int freq_imin = tx_min_freq;
  108.  int freq_imax = tx_max_freq;
  109.  double freq_dmin = tx_min_freq / 100;
  110.  double freq_dmax = tx_max_freq / 100;
  111. if (more_options == 0) {
  112.    printf("Usage: %s freq (MHz) i.e. 88.1, 99, 106.95\n",prog);
  113.    printf("Or: %s --help (for more options)\n\n",prog);
  114.   return 1;
  115. } else
  116.  {
  117.    printf("Usage: %s [freq] [options]\n\n",prog);
  118.    printf("[freq] [%.2f - %.2f](MHz) 88.1, 99, 106.95\n",freq_dmin,freq_dmax);
  119.    printf("[freq] [%i - %i] as 8810, 9900, 10695\n",freq_imin, freq_imax);
  120.    printf("[freq] off (disable FM transmitter)\n\n");
  121.    printf("[Options] can omit [freq] except for DSP and TX power\n");
  122.    printf("(FM mode) s, stereo,  m,  mono (default = Stereo)\n");
  123.    printf("(Pre-emphasis) 50, 50us, 75, 75us (default = 50us)\n");
  124.    printf("(Audio volume) v0, v1, v2, v3, v4, v5 (default = v1)\n");
  125.    printf("(DSP volume) dsp [0 - 56] (default = dsp 52)\n");
  126.    printf("[freq] (TX power) l, low, h, high (default = high)\n\n");
  127.    return 0;
  128.  }
  129. }
  130. int keene_sendget(usb_dev_handle *handle, char *senddata ) {
  131.     unsigned char buf[64];
  132.     int rc;
  133.  
  134.     memcpy(buf, senddata, 0x0000008);
  135.     rc = usb_control_msg(handle, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 0x0000009, 0x0000200, 0x0000002, buf, 0x0000008, 1000);
  136.     //printf("30 control msg returned %d", rc);
  137.     //printf("\n");
  138.  
  139.     if(rc < 0) {
  140.             perror(" ! Transfer error");
  141.         cleanup();
  142.     }
  143. }
  144.  
  145. // ** main() ********************************************************
  146. int main(int argc, char *argv[]) {
  147.     int rc;
  148.     int freq_h;
  149.     int freq_l;
  150.     int freq_in = 0;
  151.     int set_mode = 0;
  152.     int valid_arg = 0;
  153.     int tx_power = 0x78; // TX power (device power is either high or low it cannot adjust)
  154.     int tx_pmax = 0x78; // 120
  155.     int tx_pmin = 0x1e; // 30
  156.     int tx_mode = 0x20; // steps: 0x00 = 0.2MHz, 0x10 = 0.1MHz, 0x20 = 0.05MHz
  157.     int tx_volume = 2; // TX volume control (not DSP)
  158.     if ((argc < 2) || (argc > 6)) {
  159.       return help(argv[0],0);
  160.     }
  161.     freq_in = atoi(argv[1]);
  162.     set_mode = 0;
  163.     if ((argc > 2) && (strcmp(argv[1], "dsp") == 0)) { set_dsp(atoi(argv[2])); }
  164.     if ((argc > 1) && (strcmp(argv[1], "m") == 0)) { set_mode = 1; valid_arg = 1; } // check for mono
  165.     if ((argc > 2) && (strcmp(argv[2], "m") == 0)) { set_mode = 1; valid_arg = 1; }
  166.     if ((argc > 3) && (strcmp(argv[3], "m") == 0)) { set_mode = 1; valid_arg = 1; }
  167.     if ((argc > 4) && (strcmp(argv[4], "m") == 0)) { set_mode = 1; valid_arg = 1; }
  168.     if ((argc > 5) && (strcmp(argv[5], "m") == 0)) { set_mode = 1; valid_arg = 1; }
  169.     if ((argc > 1) && (strcmp(argv[1], "mono") == 0)) { set_mode = 1; valid_arg = 1; }
  170.     if ((argc > 2) && (strcmp(argv[2], "mono") == 0)) { set_mode = 1; valid_arg = 1; }
  171.     if ((argc > 3) && (strcmp(argv[3], "mono") == 0)) { set_mode = 1; valid_arg = 1; }
  172.     if ((argc > 4) && (strcmp(argv[4], "mono") == 0)) { set_mode = 1; valid_arg = 1; }
  173.     if ((argc > 5) && (strcmp(argv[5], "mono") == 0)) { set_mode = 1; valid_arg = 1; }
  174.  
  175.     if ((argc > 1) && (strcmp(argv[1], "s") == 0)) { set_mode = 0; valid_arg = 1; } // check for stereo
  176.     if ((argc > 2) && (strcmp(argv[2], "s") == 0)) { set_mode = 0; valid_arg = 1; }
  177.     if ((argc > 3) && (strcmp(argv[3], "s") == 0)) { set_mode = 0; valid_arg = 1; }
  178.     if ((argc > 4) && (strcmp(argv[4], "s") == 0)) { set_mode = 0; valid_arg = 1; }
  179.     if ((argc > 5) && (strcmp(argv[5], "s") == 0)) { set_mode = 0; valid_arg = 1; }
  180.     if ((argc > 1) && (strcmp(argv[1], "stereo") == 0)) { set_mode = 0; valid_arg = 1; }
  181.     if ((argc > 2) && (strcmp(argv[2], "stereo") == 0)) { set_mode = 0; valid_arg = 1; }
  182.     if ((argc > 3) && (strcmp(argv[3], "stereo") == 0)) { set_mode = 0; valid_arg = 1; }
  183.     if ((argc > 4) && (strcmp(argv[4], "stereo") == 0)) { set_mode = 0; valid_arg = 1; }
  184.     if ((argc > 5) && (strcmp(argv[5], "stereo") == 0)) { set_mode = 0; valid_arg = 1; }
  185.  
  186.     tx_mode = tx_mode + set_mode;
  187.     set_mode = 0;
  188.  
  189.     if ((argc > 1) && (strcmp(argv[1], "75us") == 0)) { set_mode = 4; valid_arg = 1; } // check for 75us pre-emphasis
  190.     if ((argc > 2) && (strcmp(argv[2], "75us") == 0)) { set_mode = 4; valid_arg = 1; }
  191.     if ((argc > 3) && (strcmp(argv[3], "75us") == 0)) { set_mode = 4; valid_arg = 1; }
  192.     if ((argc > 4) && (strcmp(argv[4], "75us") == 0)) { set_mode = 4; valid_arg = 1; }
  193.     if ((argc > 5) && (strcmp(argv[5], "75us") == 0)) { set_mode = 4; valid_arg = 1; }
  194.     if ((argc > 1) && (strcmp(argv[1], "75") == 0)) { set_mode = 4; valid_arg = 1; }
  195.     if ((argc > 2) && (strcmp(argv[2], "75") == 0)) { set_mode = 4; valid_arg = 1; }
  196.     if ((argc > 3) && (strcmp(argv[3], "75") == 0)) { set_mode = 4; valid_arg = 1; }
  197.     if ((argc > 4) && (strcmp(argv[4], "75") == 0)) { set_mode = 4; valid_arg = 1; }
  198.     if ((argc > 5) && (strcmp(argv[5], "75") == 0)) { set_mode = 4; valid_arg = 1; }
  199.  
  200.     if ((argc > 1) && (strcmp(argv[1], "50us") == 0)) { set_mode = 0; valid_arg = 1; } // check for 50us pre-emphasis
  201.     if ((argc > 2) && (strcmp(argv[2], "50us") == 0)) { set_mode = 0; valid_arg = 1; }
  202.     if ((argc > 3) && (strcmp(argv[3], "50us") == 0)) { set_mode = 0; valid_arg = 1; }
  203.     if ((argc > 4) && (strcmp(argv[4], "50us") == 0)) { set_mode = 0; valid_arg = 1; }
  204.     if ((argc > 5) && (strcmp(argv[5], "50us") == 0)) { set_mode = 0; valid_arg = 1; }
  205.     if ((argc > 1) && (strcmp(argv[1], "50") == 0)) { set_mode = 0; valid_arg = 1; }
  206.     if ((argc > 2) && (strcmp(argv[2], "50") == 0)) { set_mode = 0; valid_arg = 1; }
  207.     if ((argc > 3) && (strcmp(argv[3], "50") == 0)) { set_mode = 0; valid_arg = 1; }
  208.     if ((argc > 4) && (strcmp(argv[4], "50") == 0)) { set_mode = 0; valid_arg = 1; }
  209.     if ((argc > 5) && (strcmp(argv[5], "50") == 0)) { set_mode = 0; valid_arg = 1; }
  210.  
  211.     if ((argc > 1) && (strcmp(argv[1], "v0") == 0)) { tx_volume = 3; valid_arg = 1; } // volume preset 0
  212.     if ((argc > 2) && (strcmp(argv[2], "v0") == 0)) { tx_volume = 3; valid_arg = 1; }
  213.     if ((argc > 3) && (strcmp(argv[3], "v0") == 0)) { tx_volume = 3; valid_arg = 1; }
  214.     if ((argc > 4) && (strcmp(argv[4], "v0") == 0)) { tx_volume = 3; valid_arg = 1; }
  215.     if ((argc > 5) && (strcmp(argv[5], "v0") == 0)) { tx_volume = 3; valid_arg = 1; }
  216.  
  217.     if ((argc > 1) && (strcmp(argv[1], "v1") == 0)) { tx_volume = 2; valid_arg = 1; } // volume preset 1
  218.     if ((argc > 2) && (strcmp(argv[2], "v1") == 0)) { tx_volume = 2; valid_arg = 1; }
  219.     if ((argc > 3) && (strcmp(argv[3], "v1") == 0)) { tx_volume = 2; valid_arg = 1; }
  220.     if ((argc > 4) && (strcmp(argv[4], "v1") == 0)) { tx_volume = 2; valid_arg = 1; }
  221.     if ((argc > 5) && (strcmp(argv[5], "v1") == 0)) { tx_volume = 2; valid_arg = 1; }
  222.  
  223.     if ((argc > 1) && (strcmp(argv[1], "v2") == 0)) { tx_volume = 4; valid_arg = 1; } // volume preset 2
  224.     if ((argc > 2) && (strcmp(argv[2], "v2") == 0)) { tx_volume = 4; valid_arg = 1; }
  225.     if ((argc > 3) && (strcmp(argv[3], "v2") == 0)) { tx_volume = 4; valid_arg = 1; }
  226.     if ((argc > 4) && (strcmp(argv[4], "v2") == 0)) { tx_volume = 4; valid_arg = 1; }
  227.     if ((argc > 5) && (strcmp(argv[5], "v2") == 0)) { tx_volume = 4; valid_arg = 1; }
  228.  
  229.     if ((argc > 1) && (strcmp(argv[1], "v3") == 0)) { tx_volume = 16; valid_arg = 1; } // volume preset 3
  230.     if ((argc > 2) && (strcmp(argv[2], "v3") == 0)) { tx_volume = 16; valid_arg = 1; }
  231.     if ((argc > 3) && (strcmp(argv[3], "v3") == 0)) { tx_volume = 16; valid_arg = 1; }
  232.     if ((argc > 4) && (strcmp(argv[4], "v3") == 0)) { tx_volume = 16; valid_arg = 1; }
  233.     if ((argc > 5) && (strcmp(argv[5], "v3") == 0)) { tx_volume = 16; valid_arg = 1; }
  234.  
  235.     if ((argc > 1) && (strcmp(argv[1], "v4") == 0)) { tx_volume = 48; valid_arg = 1; } // volume preset 4
  236.     if ((argc > 2) && (strcmp(argv[2], "v4") == 0)) { tx_volume = 48; valid_arg = 1; }
  237.     if ((argc > 3) && (strcmp(argv[3], "v4") == 0)) { tx_volume = 48; valid_arg = 1; }
  238.     if ((argc > 4) && (strcmp(argv[4], "v4") == 0)) { tx_volume = 48; valid_arg = 1; }
  239.     if ((argc > 5) && (strcmp(argv[5], "v4") == 0)) { tx_volume = 48; valid_arg = 1; }
  240.  
  241.     if ((argc > 1) && (strcmp(argv[1], "v5") == 0)) { tx_volume = 80; valid_arg = 1; } // volume preset 5
  242.     if ((argc > 2) && (strcmp(argv[2], "v5") == 0)) { tx_volume = 80; valid_arg = 1; }
  243.     if ((argc > 3) && (strcmp(argv[3], "v5") == 0)) { tx_volume = 80; valid_arg = 1; }
  244.     if ((argc > 4) && (strcmp(argv[4], "v5") == 0)) { tx_volume = 80; valid_arg = 1; }
  245.     if ((argc > 5) && (strcmp(argv[5], "v5") == 0)) { tx_volume = 80; valid_arg = 1; }
  246.  
  247.     tx_mode = tx_mode + set_mode;
  248.  
  249.     if (strcmp(argv[1], "--help") == 0) {
  250.         return help(argv[0],1);
  251.     }
  252.     double freq_d = strtod(argv[1],NULL);
  253.     if (strcmp(argv[1], "off") == 0) { freq_in = tx_off_freq; tx_power = tx_pmin; valid_arg =2; }
  254.     if ( freq_in < 200 ) { freq_in =(int)(freq_d * 100); }  // if < 200 assume decimal value is used
  255.     if ((valid_arg == 0) && (freq_in != tx_off_freq)) {     // don't check range if special arguments are used
  256.     if ((freq_in < tx_min_freq)||(freq_in > tx_max_freq)) { // check for frequency in range
  257.           printf("Frequency out of range\n");
  258.           cleanup();
  259.         }
  260.       }
  261.     if ((argc > 1) && (strcmp(argv[1], "high") == 0)) { tx_power = tx_pmax; valid_arg = 3; } // check for high TX power
  262.     if ((argc > 2) && (strcmp(argv[2], "high") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  263.     if ((argc > 3) && (strcmp(argv[3], "high") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  264.     if ((argc > 4) && (strcmp(argv[4], "high") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  265.     if ((argc > 5) && (strcmp(argv[5], "high") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  266.     if ((argc > 6) && (strcmp(argv[6], "high") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  267.     if ((argc > 1) && (strcmp(argv[1], "h") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  268.     if ((argc > 2) && (strcmp(argv[2], "h") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  269.     if ((argc > 3) && (strcmp(argv[3], "h") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  270.     if ((argc > 4) && (strcmp(argv[4], "h") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  271.     if ((argc > 5) && (strcmp(argv[5], "h") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  272.     if ((argc > 6) && (strcmp(argv[6], "h") == 0)) { tx_power = tx_pmax; valid_arg = 3; }
  273.     if ((argc > 1) && (strcmp(argv[1], "low") == 0)) { tx_power = tx_pmin; valid_arg = 3; } // check for low TX power
  274.     if ((argc > 2) && (strcmp(argv[2], "low") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  275.     if ((argc > 3) && (strcmp(argv[3], "low") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  276.     if ((argc > 4) && (strcmp(argv[4], "low") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  277.     if ((argc > 5) && (strcmp(argv[5], "low") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  278.     if ((argc > 6) && (strcmp(argv[6], "low") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  279.     if ((argc > 1) && (strcmp(argv[1], "l") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  280.     if ((argc > 2) && (strcmp(argv[2], "l") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  281.     if ((argc > 3) && (strcmp(argv[3], "l") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  282.     if ((argc > 4) && (strcmp(argv[4], "l") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  283.     if ((argc > 5) && (strcmp(argv[5], "l") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  284.     if ((argc > 6) && (strcmp(argv[6], "l") == 0)) { tx_power = tx_pmin; valid_arg = 3; }
  285.  
  286.     if ((valid_arg == 3) && (argc == 2)) {
  287.       printf("Error: you must set the frequency before adjusting TX power\n");
  288.       return 1;
  289.     }
  290.  
  291.     unsigned char hexdata[64];
  292.     freq_in = ((freq_in - 7600)/5); // convert to counter ($0000 = 76MHz, $0001 = 76.05MHz etc)
  293.     freq_h = (freq_in / 256);
  294.     freq_l = (freq_in - (freq_h * 256));
  295.     hexdata[0]=0x00;
  296.     hexdata[1]=0x50;
  297.     hexdata[2]=freq_h;
  298.     hexdata[3]=freq_l;
  299.     hexdata[4]=tx_power;
  300.     hexdata[5]=0x19;
  301.     hexdata[6]=0x00;
  302.     hexdata[7]=0x44; // 0x44 tune up, 0x4D tune down
  303.     keenehandle = GetFirstDevice(keeneVID,keenePID);
  304.     //fprintf (stderr,"%d freq_3 %x freqhex %s hexdata \n",freq_3,freq_3,hexdata);
  305.  
  306.     keenehandle = GetFirstDevice(keeneVID,keenePID);
  307.  
  308.     // Find the USB connect
  309.     if (!keenehandle) {
  310.         perror(" ! Error opening device!");
  311.         exit(errno);
  312.     }
  313.  
  314.     // See if we can talk to the device.
  315.     rc = usb_claim_interface(keenehandle,2);
  316.     // If not, we might need to wrestle the keene off the HID driver
  317.     if (rc==-16) {
  318.         //need to grab the device the second bit of the HID device
  319.             rc = usb_detach_kernel_driver_np(keenehandle,2);
  320.             if(rc < 0) {
  321.                 perror(" ! usbhid wouldn't let go?");
  322.                 cleanup();
  323.             }
  324.         // try again
  325.         rc = usb_claim_interface(keenehandle,2);
  326.     }
  327.  
  328.     // Claim the interface
  329.     rc = usb_claim_interface(keenehandle,2);
  330.     if(rc < 0) {
  331.         perror(" ! Error claiming the interface(2) - you must run with root privileges");
  332.         cleanup();
  333.     }
  334.  
  335.     if (freq_in > 0) {
  336.       if (valid_arg > 1) { // change tx power by tuning frequency out and in
  337.         int temp_h,temp_l; // it cannot adjust power if frequency is unchanged
  338.         temp_h = hexdata[2];
  339.         temp_l = hexdata[3];
  340.         freq_in = ((tx_off_freq - 7600)/5);
  341.         freq_h = (freq_in / 256);
  342.         freq_l = (freq_in - (freq_h * 256));
  343.         hexdata[2]=freq_h;
  344.         hexdata[3]=freq_l;
  345.         keene_sendget(keenehandle,hexdata); // set TX to tx_freq_off
  346.         hexdata[2] = temp_h;
  347.         hexdata[3] = temp_l;
  348.       }
  349.       keene_sendget(keenehandle,hexdata); // set TX frequency
  350.     }
  351.     hexdata[0]=0x00;
  352.     hexdata[1]=0x51;
  353.     hexdata[2]=tx_volume;
  354.     hexdata[3]=tx_mode;
  355.     hexdata[4]=0x00;
  356.     hexdata[5]=0x00;
  357.     hexdata[6]=0x00;
  358.     hexdata[7]=0x44;
  359.     keene_sendget(keenehandle,hexdata); // set TX options
  360.  
  361.     cleanup();
  362. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×