Files
openairinterface5g/openair1/PHY/TOOLS/smbv.c
T

622 lines
20 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
This library offers some functions to remotely program the R&S SMBV100A.
*/
#include "smbv.h"
#ifndef CONFIG_SMBV
int smbv_post_processing(const char* fname)
{
/*FILE *f_ptr;
Issue seems to be fixed in latest firmware
int sleep_time = 1e6; // this is a second
// this command appends all occurrences of CW:DSEL at the end of the config file.
// this is necessary because as soon as a user is configured in the SMBV, the already selected data list get reset to PN9
// maybe that is a bug in the SMBV...
char shell_cmd[256] = "cat ";
strcat(shell_cmd,fname);
strcat(shell_cmd," | grep \"CW:DATA DLIS\" | cat >> ");
strcat(shell_cmd,fname);
// msg("Command: %s\n",shell_cmd);
popen(shell_cmd,"r");
usleep(sleep_time); // make sure shell command completes
// Turn on EUTRA
// fprintf(f_ptr, "BB:EUTR:STAT ON\n");
fclose(f_ptr); */
return 0;
}
int smbv_init_config(const char* fname, uint16_t sequence_length)
{
FILE *f_ptr;
int k;
f_ptr = fopen(fname,"w");
if (!f_ptr)
return -1;
if (sequence_length>4) {
msg("ERROR invalid sequence length: %d, maximum is 4\n", sequence_length);
fclose(f_ptr);
return -1;
} else
slen = sequence_length;
fprintf(f_ptr, "*RST;*CLS\n");
fprintf(f_ptr, "BB:EUTR:PRES\n");
fprintf(f_ptr, "FREQ 1.9076 GHZ\n");
fprintf(f_ptr, "BB:EUTR:LINK DOWN\n");
fprintf(f_ptr, "BB:EUTR:DL:BUR DTX\n"); // unallocated resource no dummy
// K55 Configuration Mode
fprintf(f_ptr, "BB:EUTR:DL:CONF:MODE AUTO\n");
// disable all PDCCH and delete all DCI entries
for (k=0; k<(10*slen); k++) {
// turn PDCCH off
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:STAT OFF\n",k);
// set USER to P-RNTI -> is not used in oai, so no risk of accidental decoding
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM0:USER PRNT\n",k);
// deleting the only item in DCI table for all SFs makes SMBV crash somehow
// selects row 0 in the DCI table
//fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:SIT 0\n",k);
// deletes row 0 in the DCI table
// fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:DEL\n",k);
}
fclose(f_ptr);
return 0;
}
int smbv_write_config_from_frame_parms(const char* fname, LTE_DL_FRAME_PARMS *frame_parms)
{
FILE *f_ptr;
f_ptr = fopen(fname,"a");
if (!f_ptr)
return -1;
fprintf(f_ptr, "BB:EUTR:SLEN %d\n",slen);
if(frame_parms->frame_type == TDD) {
fprintf(f_ptr, "BB:EUTR:DUPL TDD\n");
} else {
fprintf(f_ptr, "BB:EUTR:DUPL FDD\n");
}
// Physical Settings
fprintf(f_ptr, "BB:EUTR:DL:BW USER\n");
fprintf(f_ptr, "BB:EUTR:DL:NORB %d\n",frame_parms->N_RB_DL);
fprintf(f_ptr, "BB:EUTR:DL:FFT %d\n",frame_parms->ofdm_symbol_size);
// TDD Frame Structure
fprintf(f_ptr, "BB:EUTR:TDD:UDC %d\n",frame_parms->tdd_config);
fprintf(f_ptr, "BB:EUTR:TDD:SPSC %d\n",frame_parms->tdd_config_S);
// MIMO
fprintf(f_ptr, "BB:EUTR:DL:MIMO:CONF TX%d\n",frame_parms->nb_antenna_ports_eNB);
fprintf(f_ptr, "BB:EUTR:DL:MIMO:ANTA ANT1\n");
fprintf(f_ptr, "BB:EUTR:DL:MIMO:ANTB NONE\n");
// Cell Specific Settings
fprintf(f_ptr, "BB:EUTR:DL:PLC:CID %d\n",frame_parms->Nid_cell);
if (frame_parms->Ncp == NORMAL) {
fprintf(f_ptr, "BB:EUTR:DL:CPC NORM\n");
} else {
fprintf(f_ptr, "BB:EUTR:DL:CPC EXT\n");
}
fprintf(f_ptr, "BB:EUTR:DL:PDSC:PB %d\n",frame_parms->pdsch_config_common.p_b);
fprintf(f_ptr, "BB:EUTR:DL:PDSC:RATB %d\n",0);
fprintf(f_ptr, "BB:EUTR:DL:PDCC:RATB %d\n",0);
fprintf(f_ptr, "BB:EUTR:DL:PBCH:RATB %d\n",0);
if (frame_parms->phich_config_common.phich_duration == normal) {
fprintf(f_ptr, "BB:EUTR:DL:PHIC:DUR NORM\n");
} else {
fprintf(f_ptr, "BB:EUTR:DL:PHIC:DUR EXT\n");
}
switch (frame_parms->phich_config_common.phich_resource) {
case oneSixth:
fprintf(f_ptr, "BB:EUTR:DL:PHIC:NGP NG1_6\n");
break;
case half:
fprintf(f_ptr, "BB:EUTR:DL:PHIC:NGP NG1_2\n");
break;
case one:
fprintf(f_ptr, "BB:EUTR:DL:PHIC:NGP NG1\n");
break;
case two:
fprintf(f_ptr, "BB:EUTR:DL:PHIC:NGP NG2\n");
break;
default:
fprintf(f_ptr, "BB:EUTR:DL:PHIC:NGP NG1_6\n");
break;
}
// Synchronization
fprintf(f_ptr, "BB:EUTR:DL:SYNC:TXAN ALL\n");
fprintf(f_ptr, "BB:EUTR:DL:SYNC:PPOW 0\n");
fprintf(f_ptr, "BB:EUTR:DL:SYNC:SPOW 0\n");
// Number of configurable SF
if (frame_parms->tdd_config == 3) {
fprintf(f_ptr, "BB:EUTR:DL:CONS %d\n",7*((slen>4) ? 4 : slen));
} else {
fprintf(f_ptr, "BB:EUTR:DL:CONS 1\n");
}
fclose(f_ptr);
return 0;
}
// This function creates a datalist for an allocation containing the data in buffer
// len is in bytes
int smbv_configure_datalist_for_alloc(const char* fname, uint8_t alloc, uint8_t subframe, uint8_t *buffer, uint32_t len)
{
FILE *f_ptr;
f_ptr = fopen(fname,"a");
if (!f_ptr)
return -1;
char strbuf[(8<<1)+1];
int i,k;
strbuf[0] = '\0';
// set data list as source
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ALL%d:CW:DATA DLIS\n",subframe,alloc);
// create data list
fprintf(f_ptr, "BB:DM:DLIS:SEL \"alloc%dsf%d\"\n",alloc,subframe);
for (k=7; k>0; k--) {
strcat(strbuf,(buffer[0]&(1<<k))?"1,":"0,");
}
strcat(strbuf,(buffer[0]&1)?"1":"0");
fprintf(f_ptr, "BB:DM:DLIS:DATA %s\n",strbuf);
strbuf[0] = '\0';
for (i=1; i<len; i++) {
for (k=7; k>0; k--) {
strcat(strbuf,(buffer[i]&(1<<k))?"1,":"0,");
}
strcat(strbuf,(buffer[i]&1)?"1":"0");
fprintf(f_ptr, "BB:DM:DLIS:DATA:APP %s\n",strbuf);
strbuf[0] = '\0';
}
// select the created data list
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ALL%d:CW:DSEL \"alloc%dsf%d\"\n",subframe,alloc,alloc,subframe);
fclose(f_ptr);
return 0;
}
int smbv_is_config_frame(uint32_t frame)
{
extern const unsigned short config_frames[MAX_CONFIG_FRAMES];
int i;
for(i=0; i<MAX_CONFIG_FRAMES; i++) {
if (config_frames[i] == frame) {
return 1;
}
}
return 0;
}
// This function creates a datalist for user containing the data in buffer
// len is in bytes
int smbv_configure_datalist_for_user(const char* fname, uint8_t user, uint8_t *buffer, uint32_t len)
{
FILE *f_ptr;
f_ptr = fopen(fname,"a");
if (!f_ptr)
return -1;
char strbuf[(8<<1)+1];
int i,k;
strbuf[0] = '\0';
// create data list
fprintf(f_ptr, "BB:DM:DLIS:SEL \"user%d\"\n",user);
for (k=7; k>0; k--) {
strcat(strbuf,(buffer[0]&(1<<k))?"1,":"0,");
}
strcat(strbuf,(buffer[0]&1)?"1":"0");
fprintf(f_ptr, "BB:DM:DLIS:DATA %s\n",strbuf);
strbuf[0] = '\0';
for (i=1; i<len; i++) {
for (k=7; k>0; k--) {
strcat(strbuf,(buffer[i]&(1<<k))?"1,":"0,");
}
strcat(strbuf,(buffer[i]&1)?"1":"0");
fprintf(f_ptr, "BB:DM:DLIS:DATA:APP %s\n",strbuf);
strbuf[0] = '\0';
}
fprintf(f_ptr, "BB:EUTR:DL:USER%d:DATA DLIS\n",user);
fprintf(f_ptr, "BB:EUTR:DL:USER%d:DSEL 'user%d'\n",user,user);
fclose(f_ptr);
return 0;
}
int smbv_configure_user(const char* fname, uint8_t user, uint8_t transmission_mode, uint16_t rnti)
{
FILE *f_ptr;
f_ptr = fopen(fname,"a");
if (!f_ptr)
return -1;
fprintf(f_ptr, "BB:EUTR:DL:USER%d:TXM M1\n",user);
fprintf(f_ptr, "BB:EUTR:DL:USER%d:UEC USER\n",user);
fprintf(f_ptr, "BB:EUTR:DL:USER%d:CCOD:STAT ON\n",user);
fprintf(f_ptr, "BB:EUTR:DL:USER%d:UEID %d\n",user,rnti);
// fprintf(f_ptr, "BB:EUTR:DL:USER2:PA \n");
fclose(f_ptr);
return 0;
};
int smbv_configure_pdcch(const char* fname,uint8_t subframe,uint8_t num_pdcch_symbols,uint8_t num_dci)
{
int k;
FILE *f_ptr;
f_ptr = fopen(fname,"a");
if (!f_ptr)
return -1;
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PCF:CREG %d\n",subframe,num_pdcch_symbols);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:FORM VAR\n",subframe);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:DCR:TRS DATA\n",subframe);
// add as many rows in the DCI table as there are number of DCIs
if (num_dci>0) {
for (k=0; k<num_dci; k++) {
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:APP\n",subframe);
}
}
fclose(f_ptr);
return 0;
}
int smbv_configure_common_dci(const char* fname, uint8_t subframe, const char* type, DCI_ALLOC_t *dci_alloc, uint8_t item)
{
FILE *f_ptr;
void *dci_pdu = &dci_alloc->dci_pdu[0];
f_ptr = fopen(fname,"a");
if (!f_ptr)
return -1;
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:STAT ON\n",subframe);
if (strcmp(type,"SI")==0)
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:USER SIRN\n",subframe,item);
else if (strcmp(type,"RA")==0) {
// msg("[SMBV] RA-RNTI %d\n",dci_alloc->rnti);
fprintf(f_ptr, "BB:EUTR:DL:CSET:RARN %d\n",dci_alloc->rnti);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:USER RARN\n",subframe,item);
} else if (strcmp(type,"PA")==0)
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:USER PRNT\n",subframe,item);
else
msg("Unknown DCI source\n");
// set PDCCH format (equivalent to log2(aggregation level))
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:PFMT %d\n",subframe,item,dci_alloc->L);
// set first CCE index
// msg("[SMBV] nCCE %d\n",dci_alloc->nCCE);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:CIND %d\n",subframe,item,dci_alloc->nCCE);
// Configure DCI
switch (dci_alloc->format) {
case format1A:
// msg("[SMBV] SF %d, Item %d, format 1A\n",subframe,item);
// msg("[SMBV] HPN %d, mcs %d, ndi %s, rba %d, rv %d, tpc %d, dai %d\n",((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs,(((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi==0)?"OFF":"ON",((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv,((DCI1A_5MHz_TDD_1_6_t *)&dci_pdu)->TPC,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIF F1A\n",subframe,item);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:F1AM PDSC\n",subframe,item);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:HPN %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:MCSR %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:NDI %s\n",subframe,item,(((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi==0)?"OFF":"ON");
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RBA %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RV %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:TPCC %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:DLA %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai);
break;
case format1C:
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIF F1C\n",subframe,item);
break;
default:
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIF F1A\n",subframe,item);
break;
}
fclose(f_ptr);
return 0;
}
int smbv_configure_ue_spec_dci(const char* fname, uint8_t subframe, uint8_t user, DCI_ALLOC_t *dci_alloc, uint8_t item)
{
FILE *f_ptr;
void *dci_pdu = &dci_alloc->dci_pdu[0];
f_ptr = fopen(fname,"a");
if (!f_ptr)
return -1;
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:STAT ON\n",subframe);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:USER USER%d\n",subframe,item,user);
// set PDCCH format (equivalent to log2(aggregation level))
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:PFMT %d\n",subframe,item,dci_alloc->L);
// set first CCE index
// msg("[SMBV] nCCE %d\n",dci_alloc->nCCE);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:CIND %d\n",subframe,item,dci_alloc->nCCE);
// Configure DCI
switch (dci_alloc->format) {
case format0:
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIF F0\n",subframe,item);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:CSIR %d\n",subframe,item,(((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req));
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:CSDM %d\n",subframe,item,((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:DLA %d\n",subframe,item,((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:MCSR %d\n",subframe,item,((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:NDI %s\n",subframe,item,(((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi==0)?"OFF":"ON");
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:PFH %s\n",subframe,item,(((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping==0)?"OFF":"ON");
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RAHR %d\n",subframe,item,((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:TPCC %d\n",subframe,item,((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC);
break;
case format1:
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIF F1\n",subframe,item);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:DLA %d\n",subframe,item,((DCI1_5MHz_TDD_t *)dci_pdu)->dai);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:HPN %d\n",subframe,item,((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:MCSR %d\n",subframe,item,((DCI1_5MHz_TDD_t *)dci_pdu)->mcs);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:NDI %s\n",subframe,item,(((DCI1_5MHz_TDD_t *)dci_pdu)->ndi==0)?"OFF":"ON");
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RAH %s\n",subframe,item,(((DCI1_5MHz_TDD_t *)dci_pdu)->rah==0)?"OFF":"ON");
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RBA %d\n",subframe,item,((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RV %d\n",subframe,item,((DCI1_5MHz_TDD_t *)dci_pdu)->rv);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:TPCC %d\n",subframe,item,((DCI1_5MHz_TDD_t *)dci_pdu)->TPC);
break;
case format1A:
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIF F1A\n",subframe,item);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:F1AM PDSC\n",subframe,item);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:HPN %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:MCSR %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:NDI %s\n",subframe,item,(((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi==0)?"OFF":"ON");
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RBA %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:RV %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:TPCC %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC);
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIC:DLA %d\n",subframe,item,((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai);
break;
default:
fprintf(f_ptr, "BB:EUTR:DL:SUBF%d:ENCC:PDCC:EXTC:ITEM%d:DCIF F1\n",subframe,item);
break;
}
fclose(f_ptr);
return 0;
}
#endif
int smbv_send_config (const char* fname, char* smbv_ip)
{
struct addrinfo hints, *res;
char *id_msg = "*IDN?\n";
int bytes_sent, status, sockfd;
char buf[BUFFER_LENGTH];
memset(buf,0,BUFFER_LENGTH);
// first, load up address structs with getaddrinfo():
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
status = getaddrinfo(smbv_ip, MYPORT, &hints, &res);
if (status!=0) {
msg("ERROR: getaddrinfo: %s\n", gai_strerror(status));
return -1;
}
// make a socket:
msg("Connecting to socket with IP %s on port %s\n",smbv_ip,MYPORT);
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
// connect!
status = connect(sockfd, res->ai_addr, res->ai_addrlen);
if (status!=0) {
msg("ERROR: connect: %s. Check IP address %s and port number %s\n", gai_strerror(status),smbv_ip, MYPORT);
}
// send command
bytes_sent = send(sockfd, id_msg, strlen(id_msg), 0);
// msg("bytes sent: %d\n",bytes_sent);
status = recv(sockfd, (void*) buf, BUFFER_LENGTH, 0);
if (status==-1) {
msg("ERROR receiving machine identification: %d\n", status);
return -1;
} else {
msg("Connected to: %s\n",buf);
}
// smbv_post_processing(fname);
smbv_configure_from_file(sockfd,fname);
// close connection
msg("Closing connection...\n");
freeaddrinfo(res);
close(sockfd);
return 0;
}
int smbv_configure_from_file(int sockfd, const char* fname)
{
FILE *f_ptr;
int ch;
char inst[MAX_INST_LENGTH];
char status[BUFFER_LENGTH];
inst[0] = '\0';
f_ptr = fopen(fname,"r");
if (f_ptr!=NULL) {
msg("Configuration file: %s\n",fname);
} else {
msg("ERROR: can't open SMBV config file: %s\n",fname);
return -1;
}
while(!feof(f_ptr)) {
ch = fgetc(f_ptr);
// putchar(ch);
strcat(inst,(char*)&ch);
if(ch == '\n') {
// strcat(inst,"*WAI\n");
// strcat(inst,"*OPC?\n");
msg("sending command: %s",inst);
// strcat(inst,"\n");
if (send(sockfd, inst, strlen(inst), 0) == -1) {
msg("ERROR sending command!\n");
}
// This code checks the SMBV if the instruction has been carried out
// recv(sockfd, (void*)status, BUFFER_LENGTH, 0);
// msg("*OPC? = \"%s\"\n",status);
// just compare first char since this must be one if the command has been applied
// usleep(100000);
/*
while(strncmp(status,"1",1)!=0) {
msg("waiting...\n");
usleep(10000);
recv(sockfd, (void*) status, BUFFER_LENGTH, 0);
// msg("*OPC? = %s, cmp %d\n",status,strncmp(status,"1",1));
}
*/
inst[0] = '\0';
}
}
msg("Done sending commands\n");
fclose(f_ptr);
return 0;
}
#ifdef CONFIG_SMBV
void help (void)
{
printf ("Usage: smbv -h -W ip_address config_file_name\n");
printf ("Compile with: gcc smbv.c -DCONFIG_SMBV -o smbv\n");
printf ("Example: ./smbv -W192.168.12.23 test_config.smbv\n");
printf ("Default IP: 192.168.12.201\n");
printf ("Default config file name: smbv_config_file.smbv\n");
}
int main(int argc,char **argv)
{
char smbv_ip[16], smbv_fname[256];
extern char *optarg;
int i;
// set default values
strcpy(smbv_ip,DEFAULT_SMBV_IP);
strcpy(smbv_fname,DEFAULT_SMBV_FNAME);
int c;
while ((c = getopt (argc, argv, "hW:")) != -1) {
switch (c) {
case 'W':
strcpy(smbv_ip,optarg);
break;
case 'h':
help();
return 0;
}
}
if (argc>2) {
strcpy(smbv_fname,argv[2]);
} else if (argc==2 && argv[1][0]!='-') {
strcpy(smbv_fname,argv[1]);
}
printf("IP = %s\n",smbv_ip);
printf("file = %s\n",smbv_fname);
smbv_send_config (smbv_fname,smbv_ip);
return 0;
}
#endif