libosmocore
0.9.3
Osmocom core library
|
00001 #pragma once 00002 00003 /* (C) 2008 by Harald Welte <laforge@gnumonks.org> 00004 * All Rights Reserved 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 * 00020 */ 00021 00022 #include <stdint.h> 00023 #include <osmocom/core/linuxlist.h> 00024 #include <osmocom/core/utils.h> 00025 #include <osmocom/core/bits.h> 00026 00039 #define MSGB_DEBUG 00040 00042 struct msgb { 00043 struct llist_head list; 00046 /* Part of which TRX logical channel we were received / transmitted */ 00047 /* FIXME: move them into the control buffer */ 00048 union { 00049 void *dst; 00050 struct gsm_bts_trx *trx; 00051 }; 00052 struct gsm_lchan *lchan; 00054 unsigned char *l1h; 00055 unsigned char *l2h; 00056 unsigned char *l3h; 00057 unsigned char *l4h; 00059 unsigned long cb[5]; 00061 uint16_t data_len; 00062 uint16_t len; 00064 unsigned char *head; 00065 unsigned char *tail; 00066 unsigned char *data; 00067 unsigned char _data[0]; 00068 }; 00069 00070 extern struct msgb *msgb_alloc(uint16_t size, const char *name); 00071 extern void msgb_free(struct msgb *m); 00072 extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg); 00073 extern struct msgb *msgb_dequeue(struct llist_head *queue); 00074 extern void msgb_reset(struct msgb *m); 00075 uint16_t msgb_length(const struct msgb *msg); 00076 extern const char *msgb_hexdump(const struct msgb *msg); 00077 00078 #ifdef MSGB_DEBUG 00079 #include <osmocom/core/panic.h> 00080 #define MSGB_ABORT(msg, fmt, args ...) do { \ 00081 osmo_panic("msgb(%p): " fmt, msg, ## args); \ 00082 } while(0) 00083 #else 00084 #define MSGB_ABORT(msg, fmt, args ...) 00085 #endif 00086 00088 #define msgb_l1(m) ((void *)(m->l1h)) 00089 00090 #define msgb_l2(m) ((void *)(m->l2h)) 00091 00092 #define msgb_l3(m) ((void *)(m->l3h)) 00093 00094 #define msgb_sms(m) ((void *)(m->l4h)) 00095 00103 static inline unsigned int msgb_l1len(const struct msgb *msgb) 00104 { 00105 return msgb->tail - (uint8_t *)msgb_l1(msgb); 00106 } 00107 00115 static inline unsigned int msgb_l2len(const struct msgb *msgb) 00116 { 00117 return msgb->tail - (uint8_t *)msgb_l2(msgb); 00118 } 00119 00127 static inline unsigned int msgb_l3len(const struct msgb *msgb) 00128 { 00129 return msgb->tail - (uint8_t *)msgb_l3(msgb); 00130 } 00131 00139 static inline unsigned int msgb_headlen(const struct msgb *msgb) 00140 { 00141 return msgb->len - msgb->data_len; 00142 } 00143 00151 static inline int msgb_tailroom(const struct msgb *msgb) 00152 { 00153 return (msgb->head + msgb->data_len) - msgb->tail; 00154 } 00155 00163 static inline int msgb_headroom(const struct msgb *msgb) 00164 { 00165 return (msgb->data - msgb->head); 00166 } 00167 00180 static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len) 00181 { 00182 unsigned char *tmp = msgb->tail; 00183 if (msgb_tailroom(msgb) < (int) len) 00184 MSGB_ABORT(msgb, "Not enough tailroom msgb_push (%u < %u)\n", 00185 msgb_tailroom(msgb), len); 00186 msgb->tail += len; 00187 msgb->len += len; 00188 return tmp; 00189 } 00190 00195 static inline void msgb_put_u8(struct msgb *msgb, uint8_t word) 00196 { 00197 uint8_t *space = msgb_put(msgb, 1); 00198 space[0] = word & 0xFF; 00199 } 00200 00205 static inline void msgb_put_u16(struct msgb *msgb, uint16_t word) 00206 { 00207 uint8_t *space = msgb_put(msgb, 2); 00208 osmo_store16be(word, space); 00209 } 00210 00215 static inline void msgb_put_u32(struct msgb *msgb, uint32_t word) 00216 { 00217 uint8_t *space = msgb_put(msgb, 4); 00218 osmo_store32be(word, space); 00219 } 00220 00225 static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len) 00226 { 00227 unsigned char *tmp = msgb->tail - len; 00228 if (msgb_length(msgb) < len) 00229 MSGB_ABORT(msgb, "msgb too small to get %u (len %u)\n", 00230 len, msgb_length(msgb)); 00231 msgb->tail -= len; 00232 msgb->len -= len; 00233 return tmp; 00234 } 00235 00240 static inline uint8_t msgb_get_u8(struct msgb *msgb) 00241 { 00242 uint8_t *space = msgb_get(msgb, 1); 00243 return space[0]; 00244 } 00245 00250 static inline uint16_t msgb_get_u16(struct msgb *msgb) 00251 { 00252 uint8_t *space = msgb_get(msgb, 2); 00253 return osmo_load16be(space); 00254 } 00255 00260 static inline uint32_t msgb_get_u32(struct msgb *msgb) 00261 { 00262 uint8_t *space = msgb_get(msgb, 4); 00263 return osmo_load32be(space); 00264 } 00265 00278 static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len) 00279 { 00280 if (msgb_headroom(msgb) < (int) len) 00281 MSGB_ABORT(msgb, "Not enough headroom msgb_push (%u < %u)\n", 00282 msgb_headroom(msgb), len); 00283 msgb->data -= len; 00284 msgb->len += len; 00285 return msgb->data; 00286 } 00287 00297 static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len) 00298 { 00299 msgb->len -= len; 00300 return msgb->data += len; 00301 } 00302 00311 static inline unsigned char *msgb_pull_to_l3(struct msgb *msg) 00312 { 00313 unsigned char *ret = msgb_pull(msg, msg->l3h - msg->data); 00314 msg->l1h = msg->l2h = NULL; 00315 return ret; 00316 } 00317 00322 static inline uint8_t msgb_pull_u8(struct msgb *msgb) 00323 { 00324 uint8_t *space = msgb_pull(msgb, 1) - 1; 00325 return space[0]; 00326 } 00327 00332 static inline uint16_t msgb_pull_u16(struct msgb *msgb) 00333 { 00334 uint8_t *space = msgb_pull(msgb, 2) - 2; 00335 return osmo_load16be(space); 00336 } 00337 00342 static inline uint32_t msgb_pull_u32(struct msgb *msgb) 00343 { 00344 uint8_t *space = msgb_pull(msgb, 4) - 4; 00345 return osmo_load32be(space); 00346 } 00347 00359 static inline void msgb_reserve(struct msgb *msg, int len) 00360 { 00361 msg->data += len; 00362 msg->tail += len; 00363 } 00364 00370 static inline int msgb_trim(struct msgb *msg, int len) 00371 { 00372 if (len > msg->data_len) 00373 return -1; 00374 00375 msg->len = len; 00376 msg->tail = msg->data + len; 00377 00378 return 0; 00379 } 00380 00386 static inline int msgb_l3trim(struct msgb *msg, int l3len) 00387 { 00388 return msgb_trim(msg, (msg->l3h - msg->data) + l3len); 00389 } 00390 00401 static inline struct msgb *msgb_alloc_headroom(int size, int headroom, 00402 const char *name) 00403 { 00404 osmo_static_assert(size > headroom, headroom_bigger); 00405 00406 struct msgb *msg = msgb_alloc(size, name); 00407 if (msg) 00408 msgb_reserve(msg, headroom); 00409 return msg; 00410 } 00411 00412 /* non inline functions to ease binding */ 00413 00414 uint8_t *msgb_data(const struct msgb *msg); 00415 void msgb_set_talloc_ctx(void *ctx); 00416