#ifndef PORTABLE_H #define PORTABLE_H /* * Architecture portability layer. * Target: Raspberry Pi 5 (BCM2712, Cortex-A76, aarch64 LP64, 8GB RAM) * and x86_64 dev host. Both are little-endian; PS/RTP/ISUP wire * formats are BIG-ENDIAN, so every multi-byte field on the wire is * built via explicit shift writers (never by casting a char* to a * wider type, which is undefined on strict-alignment ABIs and * endian-wrong on any host). */ #include #include #include #include #include #include /* char is UNSIGNED by default on the ARM AAPCS (aarch64). Never rely on * signedness of plain char for byte values: always use uint8_t or int. */ /* Fixed-width, ABI-stable types. On LP64 'long' is 8 bytes while on ILP32 * it is 4; we therefore avoid long/int for cross-arch fields. */ typedef int32_t hk_i32; typedef uint32_t hk_u32; typedef int64_t hk_i64; typedef uint64_t hk_u64; /* Big-endian byte writers (wire order). Unaligned-safe via memcpy, correct * on x86_64 and aarch64 alike. */ static inline void be_write16(uint8_t *p, uint16_t v){ p[0]=(uint8_t)(v>>8); p[1]=(uint8_t)v; } static inline void be_write24(uint8_t *p, uint32_t v){ p[0]=(uint8_t)(v>>16); p[1]=(uint8_t)(v>>8); p[2]=(uint8_t)v; } static inline void be_write32(uint8_t *p, uint32_t v){ p[0]=(uint8_t)(v>>24); p[1]=(uint8_t)(v>>16); p[2]=(uint8_t)(v>>8); p[3]=(uint8_t)v; } static inline void be_write48(uint8_t *p, uint64_t v){ for(int i=0;i<6;i++) p[i]=(uint8_t)(v>>((5-i)*8)); } /* Big-endian readers */ static inline uint16_t be_read16(const uint8_t *p){ return (uint16_t)((p[0]<<8)|p[1]); } static inline uint32_t be_read32(const uint8_t *p){ return ((uint32_t)p[0]<<24)|((uint32_t)p[1]<<16)|((uint32_t)p[2]<<8)|(uint32_t)p[3]; } /* Monotonic milliseconds (immune to wall-clock jumps / NTP on Pi). */ int64_t portable_now_ms(void); /* Portable sleep (nanosleep; usleep is deprecated on newer glibc). */ void portable_sleep_ms(int ms); /* Configure a thread with an explicit stack size (Pi5 default 8MB is fine, * but big PS buffers are heap-allocated so worker threads get a modest * 256KB stack -> predictable on 8GB board and embedded builds). */ int portable_thread_create(pthread_t *t, void*(*fn)(void*), void*arg, size_t stack_bytes); #endif /* PORTABLE_H */