Changeset 7:e5af94b04946 in freeDiameter for libfreeDiameter/messages.c
- Timestamp:
- Sep 4, 2009, 6:05:25 PM (15 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfreeDiameter/messages.c
r4 r7 2138 2138 2139 2139 /***************************************************************************************************************/ 2140 /* Macro to check if further callbacks must be called */ 2141 #define TEST_ACTION_STOP() \ 2142 if ((*msg == NULL) || (*action != DISP_ACT_CONT)) \ 2143 goto no_error; 2144 2145 /* Call all dispatch callbacks for a given message */ 2146 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action) 2147 { 2148 struct dictionary * dict; 2149 struct dict_object * app; 2150 struct dict_object * cmd; 2151 struct avp * avp; 2152 struct fd_list * cb_list; 2153 int ret = 0; 2154 2155 TRACE_ENTRY("%p %p %p", msg, session, action); 2156 CHECK_PARAMS( msg && CHECK_MSG(*msg) && action); 2157 2158 /* Take the dispatch lock */ 2159 CHECK_FCT( pthread_rwlock_rdlock(&fd_disp_lock) ); 2160 pthread_cleanup_push( fd_cleanup_rwlock, &fd_disp_lock ); 2161 2162 /* First, call the DISP_HOW_ANY callbacks */ 2163 CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL ), goto error ); 2164 2165 TEST_ACTION_STOP(); 2166 2167 /* If we don't know the model at this point, we stop cause we cannot get the dictionary. It's invalid: an error should already have been trigged by ANY callbacks */ 2168 CHECK_PARAMS_DO(cmd = (*msg)->msg_model, { ret = EINVAL; goto error; } ); 2169 2170 /* Now resolve message application */ 2171 CHECK_FCT_DO( ret = fd_dict_getdict( cmd, &dict ), goto error ); 2172 CHECK_FCT_DO( ret = fd_dict_search( dict, DICT_APPLICATION, APPLICATION_BY_ID, &(*msg)->msg_public.msg_appl, &app, 0 ), goto error ); 2173 2174 if (app == NULL) { 2175 /* In that case, maybe we should answer a DIAMETER_APPLICATION_UNSUPPORTED error ? Do we do this here ? */ 2176 TRACE_DEBUG(NONE, "Reply DIAMETER_APPLICATION_UNSUPPORTED if it's a request ?"); 2177 } 2178 2179 /* So start browsing the message */ 2180 CHECK_FCT_DO( ret = fd_msg_browse( *msg, MSG_BRW_FIRST_CHILD, &avp, NULL ), goto error ); 2181 while (avp != NULL) { 2182 /* Sanity */ 2183 ASSERT( avp->avp_public.avp_value ); 2184 2185 /* For unknown AVP, we don't have a callback registered, so just skip */ 2186 if (avp->avp_model) { 2187 struct dict_object * type, * enumval; 2188 2189 /* Get the list of callback for this AVP */ 2190 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_AVP, avp->avp_model, &cb_list), goto error ); 2191 2192 /* Check if the AVP has a constant value */ 2193 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &type, 0), goto error ); 2194 if (type) { 2195 struct dict_enumval_request req; 2196 memset(&req, 0, sizeof(struct dict_enumval_request)); 2197 req.type_obj = type; 2198 memcpy( &req.search.enum_value, avp->avp_public.avp_value, sizeof(union avp_value) ); 2199 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enumval, 0), goto error ); 2200 } else { 2201 /* No enumerated value in this case */ 2202 enumval = NULL; 2203 } 2204 2205 /* Call the callbacks */ 2206 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval ), goto error ); 2207 TEST_ACTION_STOP(); 2208 } 2209 /* Go to next AVP */ 2210 CHECK_FCT_DO( ret = fd_msg_browse( avp, MSG_BRW_WALK, &avp, NULL ), goto error ); 2211 } 2212 2213 /* Now call command and application callbacks */ 2214 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto error ); 2215 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto error ); 2216 TEST_ACTION_STOP(); 2217 2218 if (app) { 2219 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto error ); 2220 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto error ); 2221 TEST_ACTION_STOP(); 2222 } 2223 2224 pthread_cleanup_pop(0); 2225 2226 no_error: 2227 CHECK_POSIX(pthread_rwlock_unlock(&fd_disp_lock) ); 2228 return 0; 2229 2230 error: 2231 CHECK_POSIX_DO(pthread_rwlock_unlock(&fd_disp_lock), /* ignore */ ); 2232 return ret; 2233 }
Note: See TracChangeset
for help on using the changeset viewer.