@@ -11,6 +11,16 @@ import { getSIP } from 'parsip';
1111class HepToLineProtocolConverter {
1212 constructor ( ) {
1313 this . debug = false ;
14+ // Default SIP headers to extract
15+ this . sipHeaders = [
16+ 'Call-ID' ,
17+ 'From' ,
18+ 'To' ,
19+ 'CSeq' ,
20+ 'User-Agent' ,
21+ ] ;
22+ // Whether to include parsed values in addition to raw values
23+ this . includeParsedValues = false ;
1424 }
1525
1626 /**
@@ -21,6 +31,25 @@ class HepToLineProtocolConverter {
2131 this . debug = ! ! enable ;
2232 }
2333
34+ /**
35+ * Set which SIP headers should be extracted
36+ * @param {Array<string> } headers - Array of SIP header names to extract
37+ */
38+ setSipHeaders ( headers ) {
39+ if ( ! Array . isArray ( headers ) ) {
40+ throw new Error ( 'SIP headers must be provided as an array' ) ;
41+ }
42+ this . sipHeaders = headers . map ( h => h . toLowerCase ( ) ) ;
43+ }
44+
45+ /**
46+ * Set whether to include parsed values in addition to raw values
47+ * @param {boolean } include - Whether to include parsed values
48+ */
49+ setIncludeParsedValues ( include ) {
50+ this . includeParsedValues = ! ! include ;
51+ }
52+
2453 /**
2554 * Process a single HEP packet and convert it to Line Protocol format
2655 * @param {Buffer } data - Raw HEP packet data
@@ -151,6 +180,24 @@ class HepToLineProtocolConverter {
151180 return tags ;
152181 }
153182
183+ /**
184+ * Extract user part from a SIP URI
185+ * @param {string } uri - The SIP URI to parse
186+ * @returns {string } The user part of the URI
187+ */
188+ extractUserFromUri ( uri ) {
189+ try {
190+ // Remove any angle brackets and extract the URI part
191+ const cleanUri = uri . replace ( / [ < > ] / g, '' ) ;
192+ // Extract the user part before the @ symbol
193+ const match = cleanUri . match ( / ^ s i p : ( [ ^ @ ] + ) @ / ) ;
194+ return match ? match [ 1 ] : cleanUri ;
195+ } catch ( e ) {
196+ if ( this . debug ) console . error ( 'Error extracting user from URI:' , e ) ;
197+ return uri ;
198+ }
199+ }
200+
154201 /**
155202 * Extract fields from HEP protocol header and payload
156203 * @param {Object } header - HEP protocol header
@@ -178,18 +225,46 @@ class HepToLineProtocolConverter {
178225 const sipData = getSIP ( payload ) ;
179226 if ( ! sipData || ! sipData . headers ) return fields ;
180227
181- // Extract method/status
182- if ( sipData . method ) fields . sip_method = sipData . method ;
183- if ( sipData . status ) fields . sip_status = parseInt ( sipData . status , 10 ) ;
228+ // Extract method/status and set the method field
229+ if ( sipData . method ) {
230+ fields . sip_method = String ( sipData . method ) ;
231+ fields . method = String ( sipData . method ) ;
232+ } else if ( sipData . status ) {
233+ fields . sip_status = parseInt ( sipData . status , 10 ) ;
234+ fields . method = String ( sipData . status ) ;
235+ }
184236
185- // Extract Call-ID directly
186- const callId = sipData . headers [ 'Call-ID' ] ;
187- if ( callId ) fields . call_id = Array . isArray ( callId ) ? callId [ 0 ] : callId ;
237+ // Process only configured headers
238+ for ( const headerName of this . sipHeaders ) {
239+ const headerValue = sipData . headers [ headerName ] ;
240+ if ( ! headerValue ) continue ;
188241
189- // Batch process headers
190- for ( const [ key , value ] of Object . entries ( sipData . headers ) ) {
191- if ( ! value ) continue ;
192- fields [ `sip_${ key . toLowerCase ( ) } ` ] = Array . isArray ( value ) ? value [ 0 ] : value ;
242+ // Handle both raw and parsed values
243+ if ( typeof headerValue === 'object' && headerValue . raw !== undefined ) {
244+ const rawValue = String ( headerValue . raw ) . trim ( ) ;
245+
246+ // Special handling for From and To headers
247+ if ( headerName . toLowerCase ( ) === 'from' || headerName . toLowerCase ( ) === 'to' ) {
248+ fields [ `${ headerName . toLowerCase ( ) } _user` ] = this . extractUserFromUri ( rawValue ) ;
249+ }
250+
251+ fields [ `sip_${ headerName . toLowerCase ( ) } ` ] = rawValue ;
252+
253+ // Optionally include parsed value if configured
254+ if ( this . includeParsedValues && headerValue . parsed ) {
255+ fields [ `sip_${ headerName . toLowerCase ( ) } _parsed` ] = JSON . stringify ( headerValue . parsed ) ;
256+ }
257+ } else {
258+ // Handle direct string values
259+ const value = Array . isArray ( headerValue ) ? headerValue [ 0 ] : headerValue ;
260+ const stringValue = String ( value . raw ) . trim ( ) ;
261+ // Special handling for From and To headers
262+ if ( headerName . toLowerCase ( ) === 'from' || headerName . toLowerCase ( ) === 'to' ) {
263+ fields [ `${ headerName . toLowerCase ( ) } _user` ] = this . extractUserFromUri ( stringValue ) ;
264+ }
265+
266+ fields [ `sip_${ headerName . toLowerCase ( ) } ` ] = stringValue ;
267+ }
193268 }
194269 } catch ( e ) {
195270 if ( this . debug ) console . error ( 'Error parsing SIP payload:' , e ) ;
0 commit comments