pothosware / SoapyPlutoSDR

Soapy SDR plugin for PlutoSDR
https://github.com/pothosware/SoapyPlutoSDR/wiki
GNU Lesser General Public License v2.1
53 stars 22 forks source link

Correct way to pass samples to API #65

Open Mas313 opened 2 weeks ago

Mas313 commented 2 weeks ago

Hi, I want to have expert opinion on passing samples to an API, i am using liquid-dsp to tranmsit and receive samples using pluto. The API performs GMSK modulation and demodulation. The program runs perfectly when run standalone with different values of 'k' and 'm' and even runs perfectly with plutosdr as long as i keep k=2 and m=3. No other values like k=26 m=4 and others invoke the receive packet call back function, somehow preamble is lost i think. The standalone code is here https://github.com/jgaeddert/liquid-dsp/blob/master/examples/gmskframesync_example.c I suspect that might be there is some circular buffering that needs to be implemented, although it works for k=2 and m=3. Followinf is my payload sending part of code

`
unsigned char payload[]="123456TxTest123456Txtest";
    payload_len=strlen(payload);
    // create frame generator and assemble
    gmskframegen fg = gmskframegen_create_set(k, m, BT);
    gmskframegen_assemble(fg, header, payload, payload_len, check, fec0, fec1);

    // allocate buffer for storing entire frame
    unsigned int num_samples = gmskframegen_getframelen(fg) + 800;
    float complex buf[num_samples];
    memset(buf, 0x00, num_samples*sizeof(float complex));

    // generate frame in one shot with sample offset
    gmskframegen_write(fg, buf+0, num_samples-0);

    int flags=0; //flags set by receive operation
    long long timeNs=1000000; //timestamp for receive buffer

    int j=num_samples;
    float complex *ptr;
    int pcount=0;
    while(run && (pcount<11) ){
                j=num_samples;
        int count=0;
        ptr=buf;
        while(j > 0){
            void *buffs[]={ptr}; //array of buffers
            int ret= SoapySDRDevice_writeStream(sdr, txStream,buffs,j,&flags,timeNs,1000000); //100000 
            //ret= SoapySDRDevice_writeStream(txStream, buffs, cnt, &flags, &timeNs, 1000000); //100000 
            //printf("After Read Stream\n");
               if (ret==SOAPY_SDR_TIMEOUT){
                printf("SOAPY_SDR_TIMEOUT\n");
            //continue;
            } 
            else if( ret==SOAPY_SDR_STREAM_ERROR ){
                printf("SOAPY_SDR_STREAM_ERROR\n");
            //continue;
            }
            else if( ret==SOAPY_SDR_CORRUPTION){
                printf("SOAPY_SDR_CORRUPTION\n");
            //continue;
            }
            else if( ret==SOAPY_SDR_OVERFLOW){
                printf("SOAPY_SDR_OVERFLOW\n");
            //continue;
            }
            else if( ret==SOAPY_SDR_NOT_SUPPORTED){
                printf("SOAPY_SDR_NOT_SUPPORTED\n");
            //continue;
            }
            else if( ret== SOAPY_SDR_TIME_ERROR){
                printf(" SOAPY_SDR_TIME_ERROR\n");
            //continue;
            }
            else if( ret== SOAPY_SDR_UNDERFLOW){
                printf(" SOAPY_SDR_UNDERFLOW\n");
            //continue;
            }
            else if (ret>0)
            {

                ;//printf("Sucesfully Sent ret=%d \n",ret);

            }

            j -= ret;
            ptr += ret;

      //printf("Bef\n");

    //printf("After\n");
    }

    printf("A Packet Sent count=%d\n",++pcount);     
    sleep(1);

    }
`

At the receiverthe thread captures and decode like this


 gmskframesync fs = gmskframesync_create_set(k, m, BT, callback, NULL);
    //int num_samples=100;
    float complex bufRx[8192]; // num_samples
    memset(bufRx, 0x00, 8192*sizeof(float complex));
    int ret;
    int flags=0; //flags set by receive operation
    long long timeNs=1000000; //timestamp for receive buffer
    printf("Thread Started \n");
    while(run){
    void *buffsRx[]={bufRx};
    ret = SoapySDRDevice_readStream(sdr, rxStream, buffsRx, 1024, &flags, &timeNs, 100000);
    // push samples through synchronizer
    if(ret>0)
        gmskframesync_execute(fs, bufRx, ret); // num_samples <->ret
    usleep(1);  
    }

This is the call back function, which only is invloked with valid and sometimes non valid data for k=2 and m=3 but not for k=26 and m=4


int callback(unsigned char *  _header,
             int              _header_valid,
             unsigned char *  _payload,
             unsigned int     _payload_len,
             int              _payload_valid,
             framesyncstats_s _stats,
             void *           _userdata)
{
    printf("***** gmskframesync callback invoked ***** RSSI=%f rxcount=%d\n",_stats.rssi,++rxCount);
    if( _header_valid && _payload_valid  ){
     printf("\n Both Header Payload Valid-----------payload Length=%d valid=%d\n",_payload_len,++valid);
     for(int a=0; a< _payload_len; a++)
    printf("%c", _payload[a]);

     }
     if( _header_valid && !_payload_valid){
     printf("\n---- Header-Only Valid-------payload Length=%d\n",_payload_len);

    }

    printf("===============================================================\n \n");
    return 0;
}

Can anyone identify my mistake ?