5 #include <trp_internal.h>
9 /* static prototypes */
10 static void *trp_route_update_new(TALLOC_CTX *mem_ctx);
11 static json_t *trp_encode_route_update(void *req_in);
12 static TRP_RC trp_parse_route_update(TRP_MSG *msg, json_t *jmsg);
13 static void trp_route_update_print(void *);
15 static void *trp_route_req_new(TALLOC_CTX *mem_ctx);
16 static json_t *trp_encode_route_req(void *req_in);
17 static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jmsg);
18 static void trp_route_req_print(void *);
20 static void *trp_msg_info_route_new(TALLOC_CTX *mem_ctx);
21 static TRP_RC trp_encode_info_route(json_t *jrec, void *route_in);
22 static TRP_RC trp_parse_info_route(TRP_MSG *msg, json_t *jmsg);
23 static void trp_msg_info_route_print(void *);
25 /* table of string names for TMT_MSG_TYPE codes */
26 struct trp_msg_type_entry {
29 void *(*allocate)(TALLOC_CTX *);
30 json_t *(*encode)(void *);
31 TRP_RC (*parse)(TRP_MSG *, json_t *);
32 void (*print)(void *);
34 static struct trp_msg_type_entry trp_msg_type_table[] = {
35 { "update", TRP_MSG_TYPE_UPDATE, trp_route_update_new, trp_encode_route_update, trp_parse_route_update, trp_route_update_print },
36 { "route_req", TRP_MSG_TYPE_ROUTE_REQ, trp_route_req_new, trp_encode_route_req, trp_parse_route_req, trp_route_req_print },
37 { NULL, TRP_MSG_TYPE_UNKNOWN, NULL, NULL, NULL, NULL } /* must be the last entry */
40 struct trp_msg_info_type_entry {
42 TRP_MSG_INFO_TYPE type;
43 void *(*allocate)(TALLOC_CTX *);
44 TRP_RC (*encode)(json_t *, void *);
45 void (*print)(void *);
47 static struct trp_msg_info_type_entry trp_msg_info_type_table[] = {
48 { "route_info", TRP_MSG_INFO_TYPE_ROUTE, trp_msg_info_route_new, trp_encode_info_route, trp_msg_info_route_print },
49 { "comm_info", TRP_MSG_INFO_TYPE_COMMUNITY, NULL, NULL, NULL },
50 { NULL, TRP_MSG_INFO_TYPE_UNKNOWN, NULL, NULL, NULL } /* must be the last entry */
53 /* Use talloc's dynamic type checking to verify type.
54 * By default, this will cause program abort, but can be overridden
55 * via talloc_set_abort_fn() if more graceful handling is needed. */
56 static void msg_body_type_check(TRP_MSG_TYPE msgtype, void *p)
59 case TRP_MSG_TYPE_UPDATE:
60 talloc_get_type_abort(p, TRP_ROUTE_UPDATE);
63 case TRP_MSG_TYPE_ROUTE_REQ:
64 talloc_get_type_abort(p, TRP_ROUTE_REQ);
72 /* look up an entry in the trp_msg_type_table */
73 static struct trp_msg_type_entry *get_trp_msg_type_entry(TRP_MSG_TYPE msgtype)
75 struct trp_msg_type_entry *entry=trp_msg_type_table;
77 while ((entry->type != TRP_MSG_TYPE_UNKNOWN)
78 && (entry->type != msgtype)) {
84 /* look up an entry in the trp_msg_info_type_table */
85 static struct trp_msg_info_type_entry *get_trp_msg_info_type_entry(TRP_MSG_INFO_TYPE msgtype)
87 struct trp_msg_info_type_entry *entry=trp_msg_info_type_table;
89 while ((entry->type != TRP_MSG_INFO_TYPE_UNKNOWN)
90 && (entry->type != msgtype)) {
96 /* translate strings to codes */
97 TRP_MSG_TYPE trp_msg_type_from_string(const char *s)
99 struct trp_msg_type_entry *entry=trp_msg_type_table;
101 while ((entry->type != TRP_MSG_TYPE_UNKNOWN)
102 && (strcmp(s, entry->name)!=0)) {
107 /* translate codes to strings (do not need to be freed)
108 * Returns NULL on an unknown code */
109 const char *trp_msg_type_to_string(TRP_MSG_TYPE msgtype)
111 struct trp_msg_type_entry *entry=get_trp_msg_type_entry(msgtype);
115 /* translate strings to codes */
116 TRP_MSG_INFO_TYPE trp_msg_info_type_from_string(const char *s)
118 struct trp_msg_info_type_entry *entry=trp_msg_info_type_table;
120 while ((entry->type != TRP_MSG_INFO_TYPE_UNKNOWN)
121 && (strcmp(s, entry->name)!=0)) {
126 /* translate codes to strings (do not need to be freed)
127 * Returns NULL on an unknown code */
128 const char *trp_msg_info_type_to_string(TRP_MSG_INFO_TYPE msgtype)
130 struct trp_msg_info_type_entry *entry=get_trp_msg_info_type_entry(msgtype);
135 TRP_MSG *trp_msg_new(TALLOC_CTX *mem_ctx)
137 TRP_MSG *new_msg=talloc(mem_ctx, TRP_MSG);
139 if (new_msg != NULL) {
140 new_msg->type=TRP_MSG_INFO_TYPE_UNKNOWN;
146 void trp_msg_destroy(TRP_MSG *msg)
154 /* Read attribute attr from msg as an integer */
155 static TRP_RC trp_get_json_integer(json_t *jmsg, const char *attr, int *dest)
160 obj=json_object_get(jmsg, attr);
165 if (!json_is_integer(obj)) {
169 (*dest)=json_integer_value(obj);
173 /* Read attribute attr from msg as a string. Copies string into mem_ctx context so jmsg can
174 * be destroyed safely. */
175 static TRP_RC trp_get_json_string(json_t *jmsg, const char *attr, char **dest, TALLOC_CTX *mem_ctx)
180 obj=json_object_get(jmsg, attr);
185 if (!json_is_string(obj))
188 *dest=talloc_strdup(mem_ctx, json_string_value(obj));
196 /* called by talloc when destroying an update message body */
197 static int trp_msg_info_route_destructor(void *object)
199 TRP_MSG_INFO_ROUTE *body=talloc_get_type_abort(object, TRP_MSG_INFO_ROUTE);
201 /* clean up TR_NAME data, which are not managed by talloc */
202 if (body->comm != NULL) {
203 tr_free_name(body->comm);
205 tr_debug("trp_msg_info_route_destructor: freed community");
207 if (body->realm != NULL) {
208 tr_free_name(body->realm);
210 tr_debug("trp_msg_info_route_destructor: freed realm");
212 if (body->trust_router != NULL) {
213 tr_free_name(body->trust_router);
214 body->trust_router=NULL;
215 tr_debug("trp_msg_info_route_destructor: freed trust_router");
221 static void *trp_msg_info_route_new(TALLOC_CTX *mem_ctx)
223 TRP_MSG_INFO_ROUTE *new_rec=talloc(mem_ctx, TRP_MSG_INFO_ROUTE);
225 if (new_rec != NULL) {
228 new_rec->trust_router=NULL;
229 new_rec->metric=TRP_METRIC_INFINITY;
231 talloc_set_destructor((void *)new_rec, trp_msg_info_route_destructor);
236 TR_NAME *trp_msg_info_route_get_comm(TRP_MSG_INFO_REC *rec)
238 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
239 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL))
245 TRP_RC trp_msg_info_route_set_comm(TRP_MSG_INFO_REC *rec, TR_NAME *comm)
247 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
248 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) {
255 TR_NAME *trp_msg_info_route_get_realm(TRP_MSG_INFO_REC *rec)
257 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
258 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL))
264 TRP_RC trp_msg_info_route_set_realm(TRP_MSG_INFO_REC *rec, TR_NAME *realm)
266 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
267 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) {
274 TR_NAME *trp_msg_info_route_get_trust_router(TRP_MSG_INFO_REC *rec)
276 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
277 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL))
278 return route->trust_router;
283 TRP_RC trp_msg_info_route_set_trust_router(TRP_MSG_INFO_REC *rec, TR_NAME *trust_router)
285 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
286 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) {
287 route->trust_router=trust_router;
293 unsigned int trp_msg_info_route_get_metric(TRP_MSG_INFO_REC *rec)
295 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
296 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL))
297 return route->metric;
299 return TRP_METRIC_INVALID;
302 TRP_RC trp_msg_info_route_set_metric(TRP_MSG_INFO_REC *rec, unsigned int metric)
304 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
305 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) {
306 route->metric=metric;
312 unsigned int trp_msg_info_route_get_interval(TRP_MSG_INFO_REC *rec)
314 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
315 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL))
316 return route->interval;
318 return TRP_INTERVAL_INVALID;
321 TRP_RC trp_msg_info_route_set_interval(TRP_MSG_INFO_REC *rec, unsigned int interval)
323 TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE);
324 if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) {
325 route->interval=interval;
331 /* generic record type */
332 static void *trp_msg_info_rec_new(TALLOC_CTX *mem_ctx, TRP_MSG_INFO_TYPE type)
334 TRP_MSG_INFO_REC *new_rec=talloc(mem_ctx, TRP_MSG_INFO_REC);
335 struct trp_msg_info_type_entry *dtype=get_trp_msg_info_type_entry(type);
337 if ((new_rec != NULL) && (dtype->type != TRP_MSG_INFO_TYPE_UNKNOWN)) {
340 if (dtype->allocate!=NULL)
341 new_rec->data=dtype->allocate(new_rec);
342 if (new_rec->data==NULL) {
343 /* dtype->allocate() failed or did not exist */
344 talloc_free(new_rec); new_rec=NULL;
350 /* parse a single record */
351 static TRP_RC trp_parse_update_record(TALLOC_CTX *mem_ctx, TRP_MSG_INFO_REC **rec, json_t *jrecord)
353 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
354 TRP_MSG_INFO_TYPE rectype;
359 rc=trp_get_json_string(jrecord, "record_type", &s, tmp_ctx);
360 if (rc != TRP_SUCCESS)
362 rectype=trp_msg_info_type_from_string(s);
363 talloc_free(s); s=NULL;
365 (*rec)=trp_msg_info_rec_new(tmp_ctx, rectype);
371 /* We only support route_info records for now*/
372 if ((*rec)->type!=TRP_MSG_INFO_TYPE_ROUTE) {
377 tr_debug("trp_parse_update_record: '%s' record found.", trp_msg_info_type_to_string((*rec)->type));
379 rc=trp_get_json_string(jrecord, "community", &s, tmp_ctx);
380 if (rc != TRP_SUCCESS)
382 if (TRP_SUCCESS!=trp_msg_info_route_set_comm(*rec, tr_new_name(s))) /* assumes route_info */
384 talloc_free(s); s=NULL;
386 rc=trp_get_json_string(jrecord, "realm", &s, tmp_ctx);
387 if (rc != TRP_SUCCESS)
389 if (TRP_SUCCESS!=trp_msg_info_route_set_realm(*rec, tr_new_name(s))) /* assumes route_info */
391 talloc_free(s); s=NULL;
393 rc=trp_get_json_string(jrecord, "trust_router", &s, tmp_ctx);
394 if (rc != TRP_SUCCESS)
396 if (TRP_SUCCESS!=trp_msg_info_route_set_trust_router(*rec, tr_new_name(s))) /* assumes route_info */
398 talloc_free(s); s=NULL;
400 rc=trp_get_json_integer(jrecord, "metric", &num);
401 if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_msg_info_route_set_metric(*rec,num)))
404 rc=trp_get_json_integer(jrecord, "interval", &num);
405 if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_msg_info_route_set_interval(*rec,num)))
408 talloc_steal(mem_ctx, *rec);
412 if (rc != TRP_SUCCESS) {
413 /* kind of a hack, assumes we only have route_info records */
414 trp_msg_info_route_destructor((*rec)->data);
417 talloc_free(tmp_ctx);
421 static void *trp_route_update_new(TALLOC_CTX *mem_ctx)
423 TRP_ROUTE_UPDATE *new_body=talloc(mem_ctx, TRP_ROUTE_UPDATE);
425 if (new_body!=NULL) {
426 new_body->records=NULL;
430 /* Parse an update body. Creates a linked list of records in the msg->body talloc context.
432 * An error will be returned if any unparseable records are encountered.
434 * TODO: clean up return codes.
435 * TODO: should take a body, not a msg */
436 static TRP_RC trp_parse_route_update(TRP_MSG *msg, json_t *jbody)
438 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
439 json_t *jrecords=NULL;
442 TRP_ROUTE_UPDATE *msg_body=NULL;
443 TRP_MSG_INFO_REC *new_rec=NULL;
444 TRP_MSG_INFO_REC *list_tail=NULL;
447 if (msg->type != TRP_MSG_TYPE_UPDATE) {
451 msg_body=talloc_get_type(msg->body, TRP_ROUTE_UPDATE);
452 if (msg_body==NULL) {
457 jrecords=json_object_get(jbody, "records");
458 if ((jrecords==NULL) || (!json_is_array(jrecords))) {
463 tr_debug("trp_parse_route_update: found %d records", json_array_size(jrecords));
464 /* process the array */
465 for (ii=0; ii<json_array_size(jrecords); ii++) {
466 if (TRP_SUCCESS != trp_parse_update_record(tmp_ctx, &new_rec, json_array_get(jrecords, ii))) {
472 msg_body->records=new_rec; /* first is a special case */
474 list_tail->next=new_rec;
479 /* Succeeded. Move all of our new allocations into the correct talloc context */
480 for (list_tail=msg_body->records; list_tail != NULL; list_tail=list_tail->next)
481 talloc_steal(msg->body, list_tail); /* all successfully parsed bodies belong to msg context */
486 talloc_free(tmp_ctx);
487 if ((rc != TRP_SUCCESS) && (msg_body != NULL))
488 msg_body->records=NULL; /* don't leave this hanging */
494 static void trp_msg_info_route_print(void *rec_in)
496 TRP_MSG_INFO_ROUTE *rec=talloc_get_type(rec_in, TRP_MSG_INFO_ROUTE); /* null if wrong type */
499 printf(" community=%.*s\n realm=%.*s\n trust_router=%.*s\n metric=%d\n interval=%d]\n",
500 rec->comm->len, rec->comm->buf,
501 rec->realm->len, rec->realm->buf,
502 rec->trust_router->len, rec->trust_router->buf,
503 rec->metric, rec->interval);
508 static int trp_route_req_destructor(void *object)
510 TRP_ROUTE_REQ *body=talloc_get_type_abort(object, TRP_ROUTE_REQ);
512 /* clean up TR_NAME data, which are not managed by talloc */
513 if (body->comm != NULL) {
514 tr_free_name(body->comm);
516 tr_debug("trp_route_req_destructor: freed community");
518 if (body->realm != NULL) {
519 tr_free_name(body->realm);
521 tr_debug("trp_route_req_destructor: freed realm");
526 void *trp_route_req_new(TALLOC_CTX *mem_ctx)
528 TRP_ROUTE_REQ *new_body=talloc(mem_ctx, TRP_ROUTE_REQ);
530 if (new_body != NULL) {
532 new_body->realm=NULL;
535 talloc_set_destructor((void *)new_body, trp_route_req_destructor);
539 void trp_route_req_set_comm(TRP_ROUTE_REQ *req, TR_NAME *comm)
544 void trp_route_req_set_realm(TRP_ROUTE_REQ *req, TR_NAME *realm)
549 /* TODO: clean up return codes.
550 * TODO: should take a body, not a msg */
551 static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jbody)
553 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
554 TRP_ROUTE_REQ *msg_body=NULL;
558 /* check message type and body type for agreement */
559 if (msg->type != TRP_MSG_TYPE_ROUTE_REQ) {
563 msg_body=talloc_get_type(msg->body, TRP_ROUTE_REQ);
564 if (msg_body==NULL) {
569 rc=trp_get_json_string(jbody, "community", &s, tmp_ctx);
572 msg_body->comm=tr_new_name(s);
573 talloc_free(s); s=NULL;
575 rc=trp_get_json_string(jbody, "realm", &s, tmp_ctx);
578 msg_body->realm=tr_new_name(s);
579 talloc_free(s); s=NULL;
583 talloc_free(tmp_ctx);
587 static json_t *trp_encode_body(TRP_MSG_TYPE type, void *body)
589 struct trp_msg_type_entry *msgtype=get_trp_msg_type_entry(type);
591 if ((msgtype->type==TRP_MSG_TYPE_UNKNOWN) || (msgtype->encode==NULL))
594 return msgtype->encode(body);
597 char *trp_encode_msg(TRP_MSG *msg)
604 jbody=trp_encode_body(msg->type, msg->body);
611 jtype=json_string(trp_msg_type_to_string(msg->type));
615 json_object_set_new(jmsg, "message_type", jtype);
616 json_object_set_new(jmsg, "body", jbody);
617 encoded=json_dumps(jmsg, 0);
625 /* add record data to jrec */
626 static TRP_RC trp_encode_info_route(json_t *jrec, void *route_in)
628 TRP_MSG_INFO_ROUTE *route=talloc_get_type(route_in, TRP_MSG_INFO_ROUTE);
636 s=tr_name_strdup(route->comm);
643 json_object_set_new(jrec, "community", jstr);
645 s=tr_name_strdup(route->realm);
652 json_object_set_new(jrec, "realm", jstr);
654 s=tr_name_strdup(route->trust_router);
661 json_object_set_new(jrec, "trust_router", jstr);
663 jint=json_integer(route->metric);
666 json_object_set_new(jrec, "metric", jint);
668 jint=json_integer(route->interval);
671 json_object_set_new(jrec, "interval", jint);
676 static json_t *trp_encode_info_rec(TRP_MSG_INFO_REC *rec)
678 struct trp_msg_info_type_entry *rectype=get_trp_msg_info_type_entry(rec->type);
682 if (rectype->type==TRP_MSG_INFO_TYPE_UNKNOWN)
689 jstr=json_string(trp_msg_info_type_to_string(rec->type));
694 json_object_set_new(jrec, "record_type", jstr);
696 if ((rectype->encode==NULL) || (TRP_SUCCESS!=rectype->encode(jrec, rec->data))) {
704 static json_t *trp_encode_route_update(void *update_in)
706 TRP_ROUTE_UPDATE *update=talloc_get_type(update_in, TRP_ROUTE_UPDATE); /* null if wrong type */
708 json_t *jrecords=NULL;
710 TRP_MSG_INFO_REC *rec;
719 jrecords=json_array();
720 if (jrecords==NULL) {
724 json_object_set_new(jbody, "records", jrecords); /* jrecords now a "borrowed" reference */
725 for (rec=update->records; rec!=NULL; rec=rec->next) {
726 jrec=trp_encode_info_rec(rec);
728 json_decref(jbody); /* also decs jrecords and any elements */
731 if (0!=json_array_append_new(jrecords, jrec)) {
732 json_decref(jbody); /* also decs jrecords and any elements */
733 json_decref(jrec); /* this one did not get added so dec explicitly */
741 static json_t *trp_encode_route_req(void *req_in)
743 TRP_ROUTE_REQ *req=talloc_get_type(req_in, TRP_ROUTE_REQ); /* null if wrong type */
755 s=tr_name_strdup(req->comm); /* ensures null termination */
766 json_object_set_new(jbody, "community", jstr);
768 s=tr_name_strdup(req->realm); /* ensures null termination */
779 json_object_set_new(jbody, "realm", jstr);
784 static void trp_msg_info_rec_print(TRP_MSG_INFO_REC *rec)
786 struct trp_msg_info_type_entry *rectype=get_trp_msg_info_type_entry(rec->type);
788 if (rectype->print != NULL) {
789 printf(" [record_type=%s\n", trp_msg_info_type_to_string(rec->type));
790 rectype->print(rec->data);
793 printf(" [record_type=%s, (no print method)]\n");
796 static void trp_route_update_print(void *body_in)
798 TRP_ROUTE_UPDATE *body=talloc_get_type(body_in, TRP_ROUTE_UPDATE); /* null if wrong type */
799 TRP_MSG_INFO_REC *rec=NULL;
802 printf(" {records=\n");
803 for (rec=body->records; rec!=NULL; rec=rec->next)
804 trp_msg_info_rec_print(rec);
809 static void trp_route_req_print(void *body_in)
811 TRP_ROUTE_REQ *body=talloc_get_type(body_in, TRP_ROUTE_REQ); /* null if wrong type */
814 printf(" {community=%.*s\n realm=%.*s}\n",
815 body->comm->len, body->comm->buf,
816 body->realm->len, body->realm->buf);
820 static void trp_msg_body_print(void *body, TRP_MSG_TYPE msgtype)
822 struct trp_msg_type_entry *info=get_trp_msg_type_entry(msgtype);
826 void trp_msg_print(TRP_MSG *msg)
828 /* right now just assumes update */
829 printf("{message_type=%s\n", trp_msg_type_to_string(msg->type));
830 trp_msg_body_print(msg->body, msg->type);
834 /* returns a pointer to one of the message body types, or NULL on error/unknown type */
835 static void *trp_msg_body_new(TALLOC_CTX *mem_ctx, TRP_MSG_TYPE msgtype)
838 struct trp_msg_type_entry *info=get_trp_msg_type_entry(msgtype);
840 if (info->type==TRP_MSG_TYPE_UNKNOWN) {
841 tr_debug("trp_msg_body_new: Unknown type %d.", info->type);
845 new_body=info->allocate(mem_ctx);
846 msg_body_type_check(msgtype, new_body); /* aborts program on type violation */
850 /* call the correct parser */
851 static TRP_RC trp_parse_msg_body(TRP_MSG *msg, json_t *jbody)
853 struct trp_msg_type_entry *info=get_trp_msg_type_entry(msg->type);
855 if (info->type==TRP_MSG_TYPE_UNKNOWN) {
856 tr_debug("trp_msg_body_parse: Unknown type %d.", info->type);
860 return info->parse(msg, jbody);
864 TRP_RC trp_parse_msg(TALLOC_CTX *mem_ctx, const char *buf, size_t buflen, TRP_MSG **msg)
866 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
867 TRP_MSG *new_msg=NULL;
868 TRP_RC msg_rc=TRP_ERROR;
869 json_error_t json_err;
870 json_t *jmsg=NULL; /* handle for the whole msg */
874 tr_debug("trp_parse_msg: parsing %d bytes", buflen);
876 jmsg=json_loadb(buf, buflen, 0, &json_err);
878 tr_debug("trp_parse_msg: Error parsing message.");
883 /* parse the common part of the message */
884 new_msg=trp_msg_new(tmp_ctx);
885 if (new_msg == NULL) {
886 tr_debug("trp_parse_msg: Error allocating message.");
891 switch (trp_get_json_string(jmsg, "message_type", &s, new_msg)) {
895 tr_debug("trp_parse_msg: required attribute 'message_type' not present.");
899 tr_debug("trp_parse_msg: required attribute 'message_type' is not a string.");
903 tr_debug("trp_parse_msg: error parsing 'message_type'.");
908 tr_debug("trp_parse_msg: 'message_type' is '%s'", s);
909 new_msg->type = trp_msg_type_from_string(s);
910 if (new_msg->type==TRP_MSG_TYPE_UNKNOWN) {
911 tr_debug("trp_parse_msg: Parsing error, unknown message_type (%s).", s);
916 new_msg->body=trp_msg_body_new(new_msg, new_msg->type);
917 if (new_msg->body==NULL) {
918 tr_debug("trp_parse_msg: Error allocating message body for message_type %d.", new_msg->type);
922 jbody=json_object_get(jmsg, "body");
924 tr_debug("trp_parse_msg: Message body not found.");
929 switch (trp_parse_msg_body(new_msg, jbody)) {
933 tr_debug("trp_parse_msg: Error parsing message body.");
940 talloc_steal(mem_ctx, *msg);
944 talloc_free(tmp_ctx);