remark release date
[Net-Radio-Location-SUPL-Test.git] / swgs / RRLP.i
blobc8c44f953f35742443e3376a25fd1ef5556d35f6
1 %{
2 enum {
3 posEstimate_type_ellipsoid_point = 0, // 0000
4 posEstimate_type_ellipsoid_point_with_uncertainty_circle = 1, // 0001
5 posEstimate_type_ellipsoid_point_with_uncertainty_ellipse = 3, // 0011
6 posEstimate_type_polygon = 5, // 0101
7 posEstimate_type_ellipsoid_point_with_altitude = 8, // 1000
8 posEstimate_type_ellipsoid_point_with_altitude_and_uncertainty_ellipse = 9, // 1001
9 posEstimate_type_ellipsoid_arc = 10, // 1010
12 struct ellipsoid_point {
13 enum {
14 ellipsoid_point_north = 0,
15 ellipsoid_point_south = 1
16 } sign_of_latitude;
17 unsigned int latitude;
18 unsigned int longitude;
21 #if __BYTE_ORDER == __LITTLE_ENDIAN
22 #define MAKE_OCTET_TUPLE2(i1,l1,i2,l2) \
23 uint8_t i2:l2; \
24 uint8_t i1:l1
25 #elif __BYTE_ORDER == __BIG_ENDIAN
26 #define MAKE_OCTET_TUPLE2(i1,l1,i2,l2) \
27 uint8_t i1:l1; \
28 uint8_t i2:l2
29 #else
30 # error "Please fix <bits/endian.h>"
31 #endif
33 struct ellipsoid_point_shape_data {
34 MAKE_OCTET_TUPLE2(sign,1, latitude_high,7);
35 uint8_t latitude_mid;
36 uint8_t latitude_low;
37 uint8_t longitude_high;
38 uint8_t longitude_mid;
39 uint8_t longitude_low;
42 struct ellipsoid_point_shape {
43 MAKE_OCTET_TUPLE2(type,4, padding,4);
44 struct ellipsoid_point_shape_data ellipsoid_point;
47 struct ellipsoid_point_shape_with_uncertainy_circle {
48 MAKE_OCTET_TUPLE2(type,4, padding,4);
49 struct ellipsoid_point_shape_data ellipsoid_point;
50 MAKE_OCTET_TUPLE2(spare,1, uncertainty_code,7);
53 struct ellipsoid_point_shape_with_uncertainy_ellipse {
54 MAKE_OCTET_TUPLE2(type,4, padding,4);
55 struct ellipsoid_point_shape_data ellipsoid_point;
56 MAKE_OCTET_TUPLE2(spare0,1, uncertainty_semi_major,7);
57 MAKE_OCTET_TUPLE2(spare1,1, uncertainty_semi_minor,7);
58 uint8_t orientation_of_major_axis;
59 MAKE_OCTET_TUPLE2(spare2,1, confidence,7);
62 struct polygon {
63 MAKE_OCTET_TUPLE2(type,4, npoints,4);
64 struct ellipsoid_point_shape_data points[];
67 enum {
68 altitude_expresses_height = 0,
69 altitude_expresses_depth = 1
72 struct ellipsoid_point_shape_with_altitude {
73 MAKE_OCTET_TUPLE2(type,4, padding,4);
74 struct ellipsoid_point_shape_data ellipsoid_point;
75 MAKE_OCTET_TUPLE2(altitude_direction,1, altitude_high,7);
76 uint8_t altitude_low;
79 struct ellipsoid_point_shape_with_altitude_and_uncertainy_ellipse {
80 MAKE_OCTET_TUPLE2(type,4, padding,4);
81 struct ellipsoid_point_shape_data ellipsoid_point;
82 MAKE_OCTET_TUPLE2(altitude_direction,1, altitude_high,7);
83 uint8_t altitude_low;
84 MAKE_OCTET_TUPLE2(spare0,1, uncertainty_semi_major,7);
85 MAKE_OCTET_TUPLE2(spare1,1, uncertainty_semi_minor,7);
86 uint8_t orientation_of_major_axis;
87 MAKE_OCTET_TUPLE2(spare2,1, uncertainty_altitude,7);
88 MAKE_OCTET_TUPLE2(spare3,1, confidence,7);
91 struct ellipsoid_arc {
92 MAKE_OCTET_TUPLE2(type,4, padding,4);
93 struct ellipsoid_point_shape_data ellipsoid_point;
94 uint8_t inner_radius_high;
95 uint8_t inner_radius_low;
96 MAKE_OCTET_TUPLE2(spare0,1, uncertainty_radius,7);
97 uint8_t offset_angle;
98 uint8_t included_angle;
99 MAKE_OCTET_TUPLE2(space1,1, confidence,7);
102 static double
103 get_fixpoint_arith_multiplier() {
104 double fpam = 1E6;
105 return fpam;
108 static void
109 encode_ellipsoid_point(struct ellipsoid_point_shape_data *point, unsigned int south, unsigned int latitude, unsigned int longitude) {
110 double dtmp;
111 unsigned int utmp;
112 int itmp;
114 point->sign = south;
116 dtmp = latitude;
117 dtmp /= get_fixpoint_arith_multiplier();
118 dtmp *= (1<<23);
119 dtmp /= 90;
120 utmp = (unsigned int)dtmp;
121 point->latitude_high = (utmp >> 16) & 0x7F;
122 point->latitude_mid = (utmp >> 8) & 0xFF;
123 point->latitude_low = utmp & 0xFF;
125 dtmp = longitude;
126 dtmp /= get_fixpoint_arith_multiplier();
127 dtmp *= (1<<24);
128 dtmp /= 360;
129 itmp = (int)dtmp;
130 point->longitude_high = (itmp >> 16) & 0xFF;
131 point->longitude_mid = (itmp >> 8) & 0xFF;
132 point->longitude_low = itmp & 0xFF;
135 static unsigned int
136 calc_uncertainty_code(unsigned int uncertainty, unsigned int C, double x) {
137 double tmp;
138 double num, denum;
140 tmp = uncertainty;
141 tmp /= C;
142 tmp += 1;
143 num = log(tmp);
145 tmp = 1 + x;
146 denum = log(tmp);
148 tmp = num/denum;
149 return (unsigned int)tmp;
152 static void *
153 prepare_geographical_information_buf(OCTET_STRING_t *posEstimate, size_t shape_size, const char *type_for_err) {
154 asn_DEF_OCTET_STRING.free_struct(&asn_DEF_OCTET_STRING, posEstimate, 1);
156 posEstimate->buf = calloc( 1, shape_size );
157 if( NULL == posEstimate->buf )
158 croak("Couldn't allocate memory to encode %s", type_for_err);
159 posEstimate->size = shape_size;
161 return posEstimate->buf;
165 %typemap(arginit) AccuracyOpt_t {
166 memset(&$1, 0, sizeof($1));
169 %typemap(in) AccuracyOpt_t {
170 if( 0 != SvOK($input) ) {
171 $1.accuracy = calloc(1, sizeof(*($1.accuracy)));
172 if( $1.accuracy ) {
173 *($1.accuracy) = SvIV($input);
175 else {
176 asn_DEF_AccuracyOpt.free_struct(&asn_DEF_AccuracyOpt, $input, 0);
177 croak("Couldn't allocate memory to transform Accuracy_t embedded attribute of AccuracyOpt_t at $argnum");
180 else {
181 $1.accuracy = NULL;
185 %typemap(in) AccuracyOpt_t * {
186 $1 = calloc(1, sizeof(*$1));
187 if( $1 ) {
188 if( 0 != SvOK($input) ) {
189 $1->accuracy = calloc(1, sizeof(*($1->accuracy)));
190 if( $1->accuracy ) {
191 *($1->accuracy) = SvIV($input);
193 else {
194 asn_DEF_AccuracyOpt.free_struct(&asn_DEF_AccuracyOpt, $input, 0);
195 croak("Couldn't allocate memory to transform Accuracy_t embedded attribute of AccuracyOpt_t at $argnum");
198 else {
199 $1->accuracy = NULL;
202 else {
203 croak("Couldn't allocate memory to transform AccuracyOpt_t at $argnum", i);
207 %typemap(out) AccuracyOpt_t {
208 if (argvi >= items) {
209 EXTEND(sp,1); /* Extend the stack by 1 object */
211 $result = sv_newmortal();
212 if(NULL != $1.accuracy) {
213 sv_setiv($result, *($1.accuracy));
215 ++argvi; /* intentional - not portable between languages */
218 %typemap(out) AccuracyOpt_t * {
219 if (argvi >= items) {
220 EXTEND(sp,1); /* Extend the stack by 1 object */
222 $result = sv_newmortal();
223 if($1 && $1->accuracy) {
224 sv_setiv($result, *($1->accuracy));
226 ++argvi; /* intentional - not portable between languages */
229 %typemap(newfree) AccuracyOpt_t "asn_DEF_AccuracyOpt.free_struct(&asn_DEF_AccuracyOpt, &$1, 1);"
230 %typemap(newfree) AccuracyOpt_t * "if( $1 ) { asn_DEF_AccuracyOpt.free_struct(&asn_DEF_AccuracyOpt, $1, 0); }"
232 %apply OCTET_STRING_t { VelocityEstimate_t };
233 %apply OCTET_STRING_t * { VelocityEstimate_t * };
234 %apply OCTET_STRING_t { Ext_GeographicalInformation_t };
235 %apply OCTET_STRING_t * { Ext_GeographicalInformation_t * };
237 %ignore asn_DEF_RRLP_Component;
238 %ignore asn_DEF_MsrPosition_Req;
239 %ignore asn_DEF_MsrPosition_Rsp;
240 %ignore asn_DEF_PositionInstruct;
241 %ignore asn_DEF_MethodType;
242 %ignore asn_DEF_ProtocolError;
243 %ignore asn_DEF_LocationInfo;
244 %ignore asn_DEF_RRLP_PDU;
246 %include "asn1/RRLP-PDU.h"
247 %include "asn1/RRLP-Component.h"
248 %include "asn1/MsrPosition-Req.h"
249 %include "asn1/MsrPosition-Rsp.h"
250 %include "asn1/PositionInstruct.h"
251 %include "asn1/MethodType.h"
252 %include "asn1/ProtocolError.h"
253 %include "asn1/LocationInfo.h"
254 %include "asn1/AssistanceData.h"
255 %include "asn1/PosCapability-Req.h"
256 %include "asn1/PosCapability-Rsp.h"
257 typedef long Accuracy_t;
258 typedef long ErrorCodes_t;
260 enum FixType {
261 FixType_twoDFix = 0,
262 FixType_threeDFix = 1
265 typedef long FixType_t;
268 %extend RRLP_PDU {
269 RRLP_PDU() {
270 struct RRLP_PDU *newobj;
271 newobj = calloc( 1, sizeof(*newobj) );
272 if( NULL == newobj )
273 croak( "Can't allocate memory for new RRLP_PDU object" );
275 return newobj;
278 RRLP_PDU(const char *data, size_t data_len) {
279 struct RRLP_PDU *newobj = NULL;
280 asn_dec_rval_t rval;
281 asn_per_data_t per_data = { data, 0, data_len * 8 };
283 rval = asn_DEF_RRLP_PDU.uper_decoder( 0, &asn_DEF_RRLP_PDU,
284 NULL, (void **)&newobj,
285 &per_data);
286 if (rval.code != RC_OK) {
287 /* Free partially decoded rrlp */
288 asn_DEF_RRLP_PDU.free_struct(
289 &asn_DEF_RRLP_PDU, newobj, 0);
291 croak("error parsing RRLP pdu on byte %u with %s",
292 (unsigned)rval.consumed,
293 asn_dec_rval_code_str(rval.code));
295 return NULL; /* unreached */
298 return newobj;
301 ~RRLP_PDU() {
302 asn_DEF_RRLP_PDU.free_struct(&asn_DEF_RRLP_PDU, $self, 1);
305 %newobject encode;
306 MsgBuffer encode() {
307 /* asn_per_data_t per_data; */
308 struct per_target_buffer per_buf;
309 asn_enc_rval_t rval = { 0 };
310 MsgBuffer retbuf = { NULL, -1 };
312 per_buf.buf = calloc( 4096, sizeof(uint8_t) );
313 per_buf.pos = 0;
314 per_buf.size = 4096;
315 rval = uper_encode(&asn_DEF_RRLP_PDU, $self, &per_output, &per_buf);
317 if (rval.encoded == -1) {
318 free(per_buf.buf);
319 croak("error encoding RRLP pdu %s: %s",
320 rval.failed_type->name,
321 strerror(errno));
323 return retbuf; /* unreached */
326 retbuf.buf = per_buf.buf;
327 retbuf.size = per_buf.pos;
329 return retbuf;
332 %newobject dump;
333 char * dump() {
334 struct per_target_buffer per_buf = { calloc( 4096, sizeof(*per_buf.buf) ), 0, 4096 };
336 asn_DEF_RRLP_PDU.print_struct(&asn_DEF_RRLP_PDU, $self, 4, &per_output, &per_buf);
338 return (char *)per_buf.buf;
341 %newobject xml_dump;
342 char * xml_dump() {
343 asn_enc_rval_t rval = { 0 };
344 struct per_target_buffer per_buf = { calloc( 4096, sizeof(*per_buf.buf) ), 0, 4096 };
346 rval = xer_encode( &asn_DEF_RRLP_PDU, $self, XER_F_BASIC, &per_output, &per_buf);
348 return (char *)per_buf.buf;
351 void set_component_type(RRLP_Component_PR kind_of)
353 if($self->component.present != RRLP_Component_PR_NOTHING) {
354 asn_DEF_RRLP_PDU.free_struct(&asn_DEF_RRLP_PDU, &$self->component, 1);
355 memset(&$self->component, 0, sizeof($self->component));
358 switch(kind_of)
360 case RRLP_Component_PR_msrPositionReq:
361 break;
362 case RRLP_Component_PR_msrPositionRsp:
363 break;
364 case RRLP_Component_PR_assistanceData:
365 break;
366 case RRLP_Component_PR_assistanceDataAck:
367 break;
368 case RRLP_Component_PR_protocolError:
369 break;
370 case RRLP_Component_PR_posCapabilityReq:
371 break;
372 case RRLP_Component_PR_posCapabilityRsp:
373 break;
374 default:
375 croak("Invalid value for component type %d, expecting between %d .. %d",
376 (int)kind_of,
377 (int)RRLP_Component_PR_msrPositionReq,
378 (int)RRLP_Component_PR_posCapabilityRsp);
380 break;
383 $self->component.present = kind_of;
385 return;
389 %nodefaultctor LocationInfo;
390 %extend LocationInfo {
391 LocationInfo(long refFrame, unsigned int fixType) {
392 struct LocationInfo *newobj;
393 if( refFrame < 0 || refFrame > 65535 )
394 croak("refFrame exceeds range (0..65535)");
396 if( fixType != FixType_twoDFix && fixType != FixType_threeDFix )
397 croak( "fixType must be one of following values: FixType_twoDFix, FixType_threeDFix" );
399 newobj = calloc( 1, sizeof(*newobj) );
400 if( NULL == newobj )
401 croak( "Can't allocate memory for new LocationInfo object" );
403 newobj->refFrame = refFrame;
404 newobj->fixType = fixType;
406 return newobj;
409 LocationInfo(long refFrame, long gpsTOW, unsigned int fixType) {
410 struct LocationInfo *newobj;
411 if( refFrame < 0 || refFrame > 65535 )
412 croak("refFrame exceeds range (0..65535)");
414 if( gpsTOW < 0 || gpsTOW > 14399999 )
415 croak("gpsTOW exceeds range (0..14399999)");
417 if( fixType != FixType_twoDFix && fixType != FixType_threeDFix )
418 croak( "fixType must be one of following values: FixType_twoDFix, FixType_threeDFix" );
420 newobj = calloc( 1, sizeof(*newobj) );
421 if( NULL == newobj )
422 croak( "Can't allocate memory for new LocationInfo object" );
424 newobj->gpsTOW = calloc( 1, sizeof(*newobj) );;
425 if( NULL == newobj->gpsTOW ) {
426 asn_DEF_LocationInfo.free_struct(&asn_DEF_LocationInfo, newobj, 0);
427 croak( "Can't allocate memory for new gpsTOW object" );
429 newobj->refFrame = refFrame;
430 *(newobj->gpsTOW) = gpsTOW;
431 newobj->fixType = fixType;
433 return newobj;
436 ~LocationInfo() {
437 asn_DEF_LocationInfo.free_struct(&asn_DEF_LocationInfo, $self, 0);
440 // posEstimate_type_ellipsoid_point = 0, // 0000
441 void set_posEstimate(unsigned int south, unsigned int latitude, unsigned int longitude) {
442 struct ellipsoid_point_shape *target;
444 target = prepare_geographical_information_buf(&$self->posEstimate, sizeof(*target), "ellipsoid point");
445 target->type = posEstimate_type_ellipsoid_point;
447 encode_ellipsoid_point( &target->ellipsoid_point, south, latitude, longitude);
449 return;
452 // posEstimate_type_ellipsoid_point_with_uncertainty_circle = 1, // 0001
453 void set_posEstimate(unsigned int south, unsigned int latitude, unsigned int longitude, unsigned uncertainty) {
454 struct ellipsoid_point_shape_with_uncertainy_circle *target;
456 target = prepare_geographical_information_buf(&$self->posEstimate, sizeof(*target), "ellipsoid point with uncertainy circle");
457 target->type = posEstimate_type_ellipsoid_point_with_uncertainty_circle;
459 encode_ellipsoid_point( &target->ellipsoid_point, south, latitude, longitude);
460 // uncertainty = C((1 + x )^K − 1) .. with C = 10 and x = 0,1.
461 target->uncertainty_code = calc_uncertainty_code(uncertainty, 10, 0.1);
463 return;
466 // posEstimate_type_ellipsoid_point_with_uncertainty_ellipse = 3, // 0011
467 void set_posEstimate(int south, unsigned int latitude, unsigned int longitude,
468 unsigned uncertainty_semi_major, unsigned uncertainty_semi_minor, unsigned orientation_of_major_axis,
469 unsigned int confidence) {
470 struct ellipsoid_point_shape_with_uncertainy_ellipse *target;
472 target = prepare_geographical_information_buf(&$self->posEstimate, sizeof(*target), "ellipsoid point with uncertainy ellipse");
473 target->type = posEstimate_type_ellipsoid_point_with_uncertainty_ellipse;
475 encode_ellipsoid_point( &target->ellipsoid_point, south, latitude, longitude);
476 // uncertainty = C((1 + x )^K − 1) .. with C = 10 and x = 0,1.
477 target->uncertainty_semi_major = calc_uncertainty_code(uncertainty_semi_major, 10, 0.1);
478 target->uncertainty_semi_minor = calc_uncertainty_code(uncertainty_semi_minor, 10, 0.1);
479 target->orientation_of_major_axis = orientation_of_major_axis / 2;
480 target->confidence = confidence;
482 return;
485 // posEstimate_type_polygon = 5, // 0101
486 void set_posEstimate(struct ellipsoid_point *points, unsigned amount) {
487 struct polygon *target;
488 unsigned i;
490 target = prepare_geographical_information_buf(&$self->posEstimate, sizeof(*target) + amount * sizeof(target->points[0]), "polygon");
491 target->type = posEstimate_type_polygon;
492 target->npoints = amount;
494 for( i = 0; i < amount; ++i ) {
495 encode_ellipsoid_point( &target->points[i], points[i].sign_of_latitude, points[i].latitude, points[i].longitude);
498 return;
501 // posEstimate_type_ellipsoid_point_with_altitude = 8, // 1000
502 void set_posEstimate(int south, unsigned int latitude, unsigned int longitude,
503 int depth_altitude, unsigned altitude) {
504 struct ellipsoid_point_shape_with_altitude *target;
506 target = prepare_geographical_information_buf(&$self->posEstimate, sizeof(*target), "ellipsoid point with altitude");
507 target->type = posEstimate_type_ellipsoid_point_with_altitude;
509 encode_ellipsoid_point( &target->ellipsoid_point, south, latitude, longitude);
511 target->altitude_direction = depth_altitude;
512 target->altitude_high = (altitude >> 8) & 0x7F;
513 target->altitude_low = altitude & 0xFF;
515 return;
518 // posEstimate_type_ellipsoid_point_with_altitude_and_uncertainty_ellipse = 9, // 1001
519 void set_posEstimate(int south, unsigned int latitude, unsigned int longitude,
520 int depth_altitude, unsigned altitude,
521 unsigned uncertainty_semi_major, unsigned uncertainty_semi_minor, unsigned orientation_of_major_axis,
522 unsigned int uncertainty_altitude, unsigned int confidence) {
523 struct ellipsoid_point_shape_with_altitude_and_uncertainy_ellipse *target;
525 target = prepare_geographical_information_buf(&$self->posEstimate, sizeof(*target), "ellipsoid point with altitude and uncertainy ellipse");
526 target->type = posEstimate_type_ellipsoid_point_with_altitude_and_uncertainty_ellipse;
528 encode_ellipsoid_point( &target->ellipsoid_point, south, latitude, longitude);
530 target->altitude_direction = depth_altitude;
531 target->altitude_high = (altitude >> 8) & 0x7F;
532 target->altitude_low = altitude & 0xFF;
534 // uncertainty = C((1 + x )^K − 1) .. with C = 10 and x = 0,1.
535 target->uncertainty_semi_major = calc_uncertainty_code(uncertainty_semi_major, 10, 0.1);
536 target->uncertainty_semi_minor = calc_uncertainty_code(uncertainty_semi_minor, 10, 0.1);
537 target->orientation_of_major_axis = orientation_of_major_axis / 2;
539 // Uncertainty Altitude h = C((1 + x )^K − 1) .. with C = 45 and x = 0,025.
540 target->uncertainty_altitude = calc_uncertainty_code(uncertainty_altitude, 45, 0.025);
542 target->confidence = confidence;
544 return;
547 // posEstimate_type_ellipsoid_arc = 10, // 1010
548 void set_posEstimate(int south, unsigned int latitude, unsigned int longitude,
549 unsigned inner_radius, unsigned uncertainty_radius, unsigned offset_angle, unsigned included_angle,
550 unsigned int confidence) {
551 struct ellipsoid_arc *target;
552 uint16_t inner;
554 target = prepare_geographical_information_buf(&$self->posEstimate, sizeof(*target), "ellipsoid arc");
555 target->type = posEstimate_type_ellipsoid_arc;
557 encode_ellipsoid_point( &target->ellipsoid_point, south, latitude, longitude);
559 inner = inner_radius / 5;
560 target->inner_radius_high = (inner >> 8) & 0xFF;
561 target->inner_radius_low = inner & 0xFF;
563 // uncertainty = C((1 + x )^K − 1) .. with C = 10 and x = 0,1.
564 target->uncertainty_radius = calc_uncertainty_code(uncertainty_radius, 10, 0.1);
566 target->offset_angle = offset_angle / 2;
567 target->included_angle = (included_angle + 1) / 2; // good enough ?
569 target->confidence = confidence;
572 static double get_fixpoint_arith_multiplier() {
573 return get_fixpoint_arith_multiplier();