Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhongxiao
OpenXG-RAN
Commits
5e1c6029
Commit
5e1c6029
authored
May 18, 2018
by
Calvin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add nr_rrc_mac_config_req_ue function
parent
42afd545
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
83 additions
and
3642 deletions
+83
-3642
openair2/LAYER2/NR_MAC_UE/config_ue.c
openair2/LAYER2/NR_MAC_UE/config_ue.c
+28
-432
openair2/LAYER2/NR_MAC_UE/defs.h
openair2/LAYER2/NR_MAC_UE/defs.h
+7
-1282
openair2/LAYER2/NR_MAC_UE/extern.h
openair2/LAYER2/NR_MAC_UE/extern.h
+0
-100
openair2/LAYER2/NR_MAC_UE/proto.h
openair2/LAYER2/NR_MAC_UE/proto.h
+0
-1193
openair2/RRC/NR_UE/defs.h
openair2/RRC/NR_UE/defs.h
+4
-366
openair2/RRC/NR_UE/rrc_UE.c
openair2/RRC/NR_UE/rrc_UE.c
+44
-62
openair2/RRC/NR_UE/vars.h
openair2/RRC/NR_UE/vars.h
+0
-207
No files found.
openair2/LAYER2/NR_MAC_UE/config_ue.c
View file @
5e1c6029
This diff is collapsed.
Click to expand it.
openair2/LAYER2/NR_MAC_UE/defs.h
View file @
5e1c6029
This diff is collapsed.
Click to expand it.
openair2/LAYER2/NR_MAC_UE/extern.h
deleted
100644 → 0
View file @
42afd545
/*
* 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
*/
/*! \file extern.h
* \brief mac externs
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \version 1.0
* \email navid.nikaein@eurecom.fr
* @ingroup _mac
*/
#ifndef __MAC_EXTERN_H__
#define __MAC_EXTERN_H__
#include "PHY/defs.h"
#include "defs.h"
#include "RRC/LITE/defs.h"
extern
const
uint32_t
BSR_TABLE
[
BSR_TABLE_SIZE
];
//extern uint32_t EBSR_Level[63];
extern
const
uint32_t
Extended_BSR_TABLE
[
BSR_TABLE_SIZE
];
//extern uint32_t Extended_BSR_TABLE[63]; ----currently not used
extern
const
uint8_t
cqi2fmt0_agg
[
MAX_SUPPORTED_BW
][
CQI_VALUE_RANGE
];
extern
const
uint8_t
cqi2fmt1x_agg
[
MAX_SUPPORTED_BW
][
CQI_VALUE_RANGE
];
extern
const
uint8_t
cqi2fmt2x_agg
[
MAX_SUPPORTED_BW
][
CQI_VALUE_RANGE
];
extern
UE_RRC_INST
*
UE_rrc_inst
;
extern
UE_MAC_INST
*
UE_mac_inst
;
extern
eNB_ULSCH_INFO
eNB_ulsch_info
[
NUMBER_OF_eNB_MAX
][
MAX_NUM_CCs
][
NUMBER_OF_UE_MAX
];
// eNBxUE = 8x8
extern
eNB_DLSCH_INFO
eNB_dlsch_info
[
NUMBER_OF_eNB_MAX
][
MAX_NUM_CCs
][
NUMBER_OF_UE_MAX
];
// eNBxUE = 8x8
#ifndef PHYSIM
#define NB_INST 1
#else
extern
unsigned
char
NB_INST
;
#endif
extern
unsigned
char
NB_eNB_INST
;
extern
unsigned
char
NB_UE_INST
;
extern
unsigned
char
NB_RN_INST
;
extern
unsigned
short
NODE_ID
[
1
];
extern
int
cqi_to_mcs
[
16
];
extern
uint32_t
RRC_CONNECTION_FLAG
;
extern
uint8_t
rb_table
[
34
];
extern
DCI0_5MHz_TDD_1_6_t
UL_alloc_pdu
;
extern
DCI1A_5MHz_TDD_1_6_t
RA_alloc_pdu
;
extern
DCI1A_5MHz_TDD_1_6_t
DLSCH_alloc_pdu1A
;
extern
DCI1A_5MHz_TDD_1_6_t
BCCH_alloc_pdu
;
extern
DCI1A_5MHz_TDD_1_6_t
CCCH_alloc_pdu
;
extern
DCI1_5MHz_TDD_t
DLSCH_alloc_pdu
;
extern
DCI0_5MHz_FDD_t
UL_alloc_pdu_fdd
;
extern
DCI1A_5MHz_FDD_t
DLSCH_alloc_pdu1A_fdd
;
extern
DCI1A_5MHz_FDD_t
RA_alloc_pdu_fdd
;
extern
DCI1A_5MHz_FDD_t
BCCH_alloc_pdu_fdd
;
extern
DCI1A_5MHz_FDD_t
CCCH_alloc_pdu_fdd
;
extern
DCI1_5MHz_FDD_t
DLSCH_alloc_pdu_fdd
;
extern
DCI2_5MHz_2A_TDD_t
DLSCH_alloc_pdu1
;
extern
DCI2_5MHz_2A_TDD_t
DLSCH_alloc_pdu2
;
extern
DCI1E_5MHz_2A_M10PRB_TDD_t
DLSCH_alloc_pdu1E
;
#endif //DEF_H
openair2/LAYER2/NR_MAC_UE/proto.h
deleted
100644 → 0
View file @
42afd545
This diff is collapsed.
Click to expand it.
openair2/RRC/NR_UE/defs.h
View file @
5e1c6029
This diff is collapsed.
Click to expand it.
openair2/RRC/NR_UE/rrc_UE.c
View file @
5e1c6029
...
@@ -143,29 +143,7 @@ uint8_t nr_rrc_ue_decode_dcch(
...
@@ -143,29 +143,7 @@ uint8_t nr_rrc_ue_decode_dcch(
}
}
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
// TODO check to use this or downer one
uint8_t
nr_rrc_ue_decode_rrcReconfiguration
(
const
uint8_t
*
buffer
,
const
uint32_t
size
){
RRCReconfiguration_t
*
rrcReconfiguration
;
// decoding
uper_decode
(
NULL
,
&
asn_DEF_RRCReconfiguration
,
(
void
**
)
&
rrcReconfiguration
,
(
uint8_t
*
)
buffer
,
size
);
nr_rrc_ue_process_rrcReconfiguration
(
rrcReconfiguration
);
// after decoder
free
(
rrcReconfiguration
);
}
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
// TODO check to use this or upper one
uint8_t
nr_rrc_ue_decode_secondary_cellgroup_config
(
uint8_t
nr_rrc_ue_decode_secondary_cellgroup_config
(
const
uint8_t
*
buffer
,
const
uint8_t
*
buffer
,
const
uint32_t
size
const
uint32_t
size
...
@@ -178,9 +156,15 @@ uint8_t nr_rrc_ue_decode_secondary_cellgroup_config(
...
@@ -178,9 +156,15 @@ uint8_t nr_rrc_ue_decode_secondary_cellgroup_config(
(
uint8_t
*
)
buffer
,
(
uint8_t
*
)
buffer
,
size
,
0
,
0
);
size
,
0
,
0
);
nr_rrc_ue_process_scg_config
(
cellGroupConfig
);
if
(
NR_UE_rrc_inst
->
cell_group_config
==
(
CellGroupConfig_t
*
)
0
){
NR_UE_rrc_inst
->
cell_group_config
=
cellGroupConfig
;
nr_rrc_ue_process_scg_config
(
cellGroupConfig
);
}
else
{
nr_rrc_ue_process_scg_config
(
cellGroupConfig
);
asn_DEF_CellGroupConfig
.
free_struct
(
asn_DEF_CellGroupConfig
,
cellGroupConfig
,
0
);
}
free
(
cellGroupConfig
);
nr_rrc_mac_config_req_ue
();
}
}
...
@@ -191,25 +175,41 @@ uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfigur
...
@@ -191,25 +175,41 @@ uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfigur
switch
(
rrcReconfiguration
.
criticalExtensions
.
present
){
switch
(
rrcReconfiguration
.
criticalExtensions
.
present
){
case
RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration
:
case
RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration
:
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
radioBearerConfig
!=
(
RadioBearerConfig_t
*
)
0
){
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
radioBearerConfig
!=
(
RadioBearerConfig_t
*
)
0
){
nr_rrc_ue_process_radio_bearer_config
(
rrcReconfiguration
->
radioBearerConfig
);
if
(
NR_UE_rrc_inst
->
radio_bearer_config
==
(
RadioBearerConfig_t
*
)
0
){
NR_UE_rrc_inst
->
radio_bearer_config
=
rrcReconfiguration
->
radioBearerConfig
;
}
else
{
nr_rrc_ue_process_radio_bearer_config
(
rrcReconfiguration
->
radioBearerConfig
);
}
}
}
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
secondaryCellGroup
!=
(
OCTET_STRING_t
*
)
0
){
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
secondaryCellGroup
!=
(
OCTET_STRING_t
*
)
0
){
CellGroupConfig_t
*
cellGroupConfig
=
(
CellGroupConfig_t
*
)
0
;
CellGroupConfig_t
*
cellGroupConfig
=
(
CellGroupConfig_t
*
)
0
;
// TODO check if this deocder is need for decode "SecondaryCellGroup" of use type "CellGroupConfig" directly
uper_decode
(
NULL
,
uper_decode
(
NULL
,
&
asn_DEF_CellGroupConfig
,
//might be added prefix later
&
asn_DEF_CellGroupConfig
,
//might be added prefix later
(
void
**
)
&
cellGroupConfig
,
(
void
**
)
&
cellGroupConfig
,
(
uint8_t
*
)
rrcReconfiguration
->
secondaryCellGroup
->
buffer
,
(
uint8_t
*
)
rrcReconfiguration
->
secondaryCellGroup
->
buffer
,
rrcReconfiguration
->
secondaryCellGroup
.
size
,
0
,
0
);
rrcReconfiguration
->
secondaryCellGroup
.
size
,
0
,
0
);
nr_rrc_ue_process_scg_config
(
cellGroupConfig
);
if
(
NR_UE_rrc_inst
->
cell_group_config
==
(
CellGroupConfig_t
*
)
0
){
// first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time.
free
(
cellGroupConfig
);
NR_UE_rrc_inst
->
cell_group_config
=
cellGroupConfig
;
nr_rrc_ue_process_scg_config
(
cellGroupConfig
);
}
else
{
// after first time, update it and free the memory after.
nr_rrc_ue_process_scg_config
(
cellGroupConfig
);
asn_DEF_CellGroupConfig
.
free_struct
(
asn_DEF_CellGroupConfig
,
cellGroupConfig
,
0
);
}
}
}
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
measConfig
!=
(
MeasConfig
*
)
0
){
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
measConfig
!=
(
MeasConfig
*
)
0
){
nr_rrc_ue_process_meas_config
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
measConfig
);
if
(
NR_UE_rrc_inst
->
meas_config
==
(
MeasConfig_t
*
)
0
){
NR_UE_rrc_inst
->
meas_config
=
rrcReconfiguration
->
measConfig
;
}
else
{
// if some element need to be updated
nr_rrc_ue_process_meas_config
(
rrcReconfiguration
->
measConfig
);
}
}
}
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
lateNonCriticalExtension
!=
(
OCTET_STRING_t
*
)
0
){
if
(
rrcReconfiguration
.
criticalExtensions
.
rrcReconfiguration
->
lateNonCriticalExtension
!=
(
OCTET_STRING_t
*
)
0
){
...
@@ -225,39 +225,18 @@ uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfigur
...
@@ -225,39 +225,18 @@ uint8_t nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration_t *rrcReconfigur
default:
default:
break
;
break
;
}
}
nr_rrc_mac_config_req_ue
();
// process
}
}
uint8_t
nr_rrc_ue_process_meas_config
(
MeasConfig_t
*
meas_config
){
uint8_t
nr_rrc_ue_process_meas_config
(
MeasConfig_t
*
meas_config
){
// copy into nr_rrc inst
memcpy
(
(
void
*
)
NR_UE_rrc_inst
->
measConfig
,
(
void
*
)
meas_config
,
sizeof
(
MeasConfig_t
));
// process it
}
}
uint8_t
nr_rrc_ue_process_scg_config
(
CellGroupConfig_t
*
cell_group_config
){
uint8_t
nr_rrc_ue_process_scg_config
(
CellGroupConfig_t
*
cell_group_config
){
// copy into nr_rrc inst
nr_ue_process_rlc_bearer_list
();
nr_ue_process_mac_cell_group_config
();
nr_ue_process_physical_cell_group_config
();
nr_ue_process_spcell_config
();
nr_ue_process_spcell_list
();
memcpy
(
(
void
*
)
NR_UE_rrc_inst
->
cellGroupConfig
,
(
void
*
)
cellGroupConfig
,
sizeof
(
cellGroupConfig_t
));
// process it
}
}
uint8_t
nr_rrc_ue_process_radio_bearer_config
(
RadioBearerConfig_t
*
radio_bearer_config
){
uint8_t
nr_rrc_ue_process_radio_bearer_config
(
RadioBearerConfig_t
*
radio_bearer_config
){
// copy into nr_rrc inst
memcpy
(
(
void
*
)
NR_UE_rrc_inst
->
radioBearerConfig
,
(
void
*
)
radio_bearer_config
,
sizeof
(
RadioBearerConfig_t
));
// process it
}
}
...
@@ -276,19 +255,22 @@ uint8_t openair_rrc_top_init_ue_nr(void){
...
@@ -276,19 +255,22 @@ uint8_t openair_rrc_top_init_ue_nr(void){
}
}
uint8_t
nr_ue_process_rlc_bearer_list
(){
uint8_t
nr_ue_process_rlc_bearer_list
(
CellGroupConfig_t
*
cell_group_config
){
};
uint8_t
nr_ue_process_mac_cell_group_config
(){
};
};
uint8_t
nr_ue_process_physical_cell_group_config
(){
uint8_t
nr_ue_process_secondary_cell_list
(
CellGroupConfig_t
*
cell_group_config
){
};
};
uint8_t
nr_ue_process_spcell_config
(){
uint8_t
nr_ue_process_mac_cell_group_config
(
MAC_CellGroupConfig_t
*
mac_cell_group_config
){
};
};
uint8_t
nr_ue_process_spcell_list
(){
uint8_t
nr_ue_process_physical_cell_group_config
(
PhysicalCellGroupConfig_t
*
phy_cell_group_config
){
};
};
uint8_t
nr_ue_process_spcell_config
(
SpCellConfig_t
*
spcell_config
){
};
openair2/RRC/NR_UE/vars.h
View file @
5e1c6029
...
@@ -37,212 +37,5 @@
...
@@ -37,212 +37,5 @@
#include "COMMON/mac_rrc_primitives.h"
#include "COMMON/mac_rrc_primitives.h"
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/defs.h"
UE_PF_PO_t
UE_PF_PO
[
MAX_NUM_CCs
][
NUMBER_OF_UE_MAX
];
pthread_mutex_t
ue_pf_po_mutex
;
NR_UE_RRC_INST_t
*
NR_UE_rrc_inst
;
NR_UE_RRC_INST_t
*
NR_UE_rrc_inst
;
#include "LAYER2/MAC/extern.h"
#define MAX_U32 0xFFFFFFFF
uint8_t
DRB2LCHAN
[
8
];
long
logicalChannelGroup0
=
0
;
long
logicalChannelSR_Mask_r9
=
0
;
struct
LogicalChannelConfig__ul_SpecificParameters
LCSRB1
=
{
1
,
LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity
,
0
,
&
logicalChannelGroup0
};
struct
LogicalChannelConfig__ul_SpecificParameters
LCSRB2
=
{
3
,
LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity
,
0
,
&
logicalChannelGroup0
};
#if defined(Rel10) || defined(Rel14)
struct
LogicalChannelConfig__ext1
logicalChannelSR_Mask_r9_ext1
=
{
logicalChannelSR_Mask_r9:
&
logicalChannelSR_Mask_r9
};
#endif
// These are the default SRB configurations from 36.331 (Chapter 9, p. 176-179 in v8.6)
LogicalChannelConfig_t
SRB1_logicalChannelConfig_defaultValue
=
{
ul_SpecificParameters
:
&
LCSRB1
#if defined(Rel10) || defined(Rel14)
,
ext1:
&
logicalChannelSR_Mask_r9_ext1
#endif
};
LogicalChannelConfig_t
SRB2_logicalChannelConfig_defaultValue
=
{
ul_SpecificParameters
:
&
LCSRB2
#if defined(Rel10) || defined(Rel14)
,
ext1:
&
logicalChannelSR_Mask_r9_ext1
#endif
};
//CONSTANTS
rlc_info_t
Rlc_info_um
,
Rlc_info_am_config
;
uint16_t
RACH_FREQ_ALLOC
;
//uint8_t NB_RACH;
LCHAN_DESC
BCCH_LCHAN_DESC
,
CCCH_LCHAN_DESC
,
DCCH_LCHAN_DESC
,
DTCH_DL_LCHAN_DESC
,
DTCH_UL_LCHAN_DESC
;
MAC_MEAS_T
BCCH_MEAS_TRIGGER
,
CCCH_MEAS_TRIGGER
,
DCCH_MEAS_TRIGGER
,
DTCH_MEAS_TRIGGER
;
MAC_AVG_T
BCCH_MEAS_AVG
,
CCCH_MEAS_AVG
,
DCCH_MEAS_AVG
,
DTCH_MEAS_AVG
;
// timers
uint16_t
T300
[
8
]
=
{
100
,
200
,
300
,
400
,
600
,
1000
,
1500
,
2000
};
uint16_t
T310
[
8
]
=
{
0
,
50
,
100
,
200
,
500
,
1000
,
2000
};
uint16_t
N310
[
8
]
=
{
1
,
2
,
3
,
4
,
6
,
8
,
10
,
20
};
uint16_t
N311
[
8
]
=
{
1
,
2
,
3
,
4
,
6
,
8
,
10
,
20
};
uint32_t
T304
[
8
]
=
{
50
,
100
,
150
,
200
,
500
,
1000
,
2000
,
MAX_U32
};
// TimeToTrigger enum mapping table (36.331 TimeToTrigger IE)
uint32_t
timeToTrigger_ms
[
16
]
=
{
0
,
40
,
64
,
80
,
100
,
128
,
160
,
256
,
320
,
480
,
512
,
640
,
1024
,
1280
,
2560
,
5120
};
/* 36.133 Section 9.1.4 RSRP Measurement Report Mapping, Table: 9.1.4-1 */
float
RSRP_meas_mapping
[
98
]
=
{
-
140
,
-
139
,
-
138
,
-
137
,
-
136
,
-
135
,
-
134
,
-
133
,
-
132
,
-
131
,
-
130
,
-
129
,
-
128
,
-
127
,
-
126
,
-
125
,
-
124
,
-
123
,
-
122
,
-
121
,
-
120
,
-
119
,
-
118
,
-
117
,
-
116
,
-
115
,
-
114
,
-
113
,
-
112
,
-
111
,
-
110
,
-
109
,
-
108
,
-
107
,
-
106
,
-
105
,
-
104
,
-
103
,
-
102
,
-
101
,
-
100
,
-
99
,
-
98
,
-
97
,
-
96
,
-
95
,
-
94
,
-
93
,
-
92
,
-
91
,
-
90
,
-
89
,
-
88
,
-
87
,
-
86
,
-
85
,
-
84
,
-
83
,
-
82
,
-
81
,
-
80
,
-
79
,
-
78
,
-
77
,
-
76
,
-
75
,
-
74
,
-
73
,
-
72
,
-
71
,
-
70
,
-
69
,
-
68
,
-
67
,
-
66
,
-
65
,
-
64
,
-
63
,
-
62
,
-
61
,
-
60
,
-
59
,
-
58
,
-
57
,
-
56
,
-
55
,
-
54
,
-
53
,
-
52
,
-
51
,
-
50
,
-
49
,
-
48
,
-
47
,
-
46
,
-
45
,
-
44
,
-
43
};
float
RSRQ_meas_mapping
[
35
]
=
{
-
19
,
-
18
.
5
,
-
18
,
-
17
.
5
,
-
17
,
-
16
.
5
,
-
16
,
-
15
.
5
,
-
15
,
-
14
.
5
,
-
14
,
-
13
.
5
,
-
13
,
-
12
.
5
,
-
12
,
-
11
.
5
,
-
11
,
-
10
.
5
,
-
10
,
-
9
.
5
,
-
9
,
-
8
.
5
,
-
8
,
-
7
.
5
,
-
7
,
-
6
.
5
,
-
6
,
-
5
.
5
,
-
5
,
-
4
.
5
,
-
4
,
-
3
.
5
,
-
3
,
-
2
.
5
,
-
2
};
// only used for RRC connection re-establishment procedure TS36.331 5.3.7
// [0]: current C-RNTI, [1]: prior C-RNTI
// insert one when eNB received RRCConnectionReestablishmentRequest message
// delete one when eNB received RRCConnectionReestablishmentComplete message
uint16_t
reestablish_rnti_map
[
NUMBER_OF_UE_MAX
][
2
]
=
{{
0
}};
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment