3 ==================================================================================
4 Copyright (c) 2020 Nokia
5 Copyright (c) 2020 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
23 Abstract: A message wrapper. This should completely hide the
24 underlying transport (RMR) message structure from
25 the user application. For the most part, the getters
26 are used by the framwork; it is unlikely that other
27 than adding/extracting the MEID, the user app will
28 be completely unaware of information that is not
29 presented in the callback parms.
32 Author: E. Scott Daniels
42 #include "message.hpp"
44 // --------------- private ------------------------------------------------
46 // --------------- builders -----------------------------------------------
49 Create a new message wrapper for an existing RMR msg buffer.
51 Message::Message( rmr_mbuf_t* mbuf, void* mrc ) {
52 this->mrc = mrc; // the message router context for sends
56 Message::Message( void* mrc, int payload_len ) {
58 this->mbuf = rmr_alloc_msg( mrc, payload_len );
73 // --- getters/setters -----------------------------------------------------
75 Copy the payload bytes, and return a smart pointer (unique) to it.
76 If the application needs to update the payload in place for a return
77 to sender call, or just to access the payload in a more efficent manner
78 (without the copy), the Get_payload() function should be considered.
80 This function will return a NULL pointer if malloc fails.
82 //char* Message::Copy_payload( ){
83 std::unique_ptr<unsigned char> Message::Copy_payload( ){
84 unsigned char* new_payload = NULL;
87 new_payload = (unsigned char *) malloc( sizeof( unsigned char ) * mbuf->len );
88 memcpy( new_payload, mbuf->payload, mbuf->len );
91 return std::unique_ptr<unsigned char>( new_payload );
95 Makes a copy of the MEID and returns a smart pointer to it.
97 std::unique_ptr<unsigned char> Message::Get_meid(){
98 unsigned char* m = NULL;
101 m = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_MEID );
102 rmr_get_meid( mbuf, m );
105 return std::unique_ptr<unsigned char>( m );
108 int Message::Get_available_size(){
110 return rmr_payload_size( mbuf );
116 int Message::Get_mtype(){
121 return INVALID_MTYPE;
125 Makes a copy of the source field and returns a smart pointer to it.
127 std::unique_ptr<unsigned char> Message::Get_src(){
128 unsigned char* m = NULL;
130 m = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_SRC );
132 rmr_get_src( mbuf, m );
135 return std::unique_ptr<unsigned char>( m );
138 int Message::Get_state( ){
143 return INVALID_STATUS;
146 int Message::Get_subid(){
151 return INVALID_SUBID;
154 int Message::Get_len(){
163 This returns a smart (unique) pointer to the payload portion of the
164 message. This provides the user application with the means to
165 update the payload in place to avoid multiple copies. The
166 user programme is responsible to determing the usable payload
167 length by calling Message:Get_available_size(), and ensuring that
168 writing beyond the indicated size does not happen.
170 Msg_component Message::Get_payload(){
172 return std::unique_ptr<unsigned char, unfreeable>( mbuf->payload );
178 void Message::Set_meid( std::unique_ptr<unsigned char> new_meid ) {
180 rmr_str2meid( mbuf, (unsigned char *) new_meid.get() );
184 void Message::Set_mtype( int new_type ){
186 mbuf->mtype = new_type;
190 void Message::Set_subid( int new_subid ){
192 mbuf->sub_id = new_subid;
197 // -------------- send functions ---------------------------------
200 This assumes that the contents of the mbuf were set by either a send attempt that
201 failed with a retry and thus is ready to be processed by RMR.
202 Exposed to the user, but not expected to be frequently used.
204 bool Message::Send( ) {
209 mbuf = rmr_send_msg( mrc, mbuf );
210 return mbuf->state == RMR_OK;
214 Similar to Send(), this assumes that the message is already set up and this is a retry.
215 Exposed to the user, but not expected to be frequently used.
217 bool Message::Reply( ) {
222 mbuf = rmr_rts_msg( mrc, mbuf );
223 return mbuf->state == RMR_OK;
228 This will setup the message (type etc.) ensure the message payload space is
229 large enough and copy in the payload (if a new payload is given), then will
230 either send or rts the message based on the stype parm.
232 If payload is nil, then we assume the user updated the payload in place and
235 This is public, but most users should use Send_msg or Send_response functions.
237 bool Message::Send( int mtype, int subid, int payload_len, unsigned char* payload, int stype ) {
244 mbuf->sub_id = subid;
245 mbuf->len = payload_len;
247 if( payload != NULL ) { // if we have a payload, ensure msg has room, realloc if needed, then copy
248 mbuf = rmr_realloc_payload( mbuf, payload_len, RMR_NO_COPY, RMR_NO_CLONE ); // ensure message is large enough
253 memcpy( mbuf->payload, payload, mbuf->len );
256 if( stype == RESPONSE ) {
257 mbuf = rmr_rts_msg( mrc, mbuf );
259 mbuf = rmr_send_msg( mrc, mbuf );
262 return mbuf->state == RMR_OK;
266 Send a response to the endpoint that sent the original message.
268 Response can be null and the assumption will be that the message payload
269 was updated in place and no additional copy is needed before sending the message.
271 The second form of the call allows for a stack allocated buffer (e.g. char foo[120]) to
272 be passed as the payload.
274 bool Message::Send_response( int mtype, int subid, int response_len, std::unique_ptr<unsigned char> response ) {
275 return Send( mtype, subid, response_len, response.get(), RESPONSE );
278 bool Message::Send_response( int mtype, int subid, int response_len, unsigned char* response ) {
279 return Send( mtype, subid, response_len, response, RESPONSE );
283 These allow a response message to be sent without changing the mtype/subid.
285 bool Message::Send_response( int response_len, std::unique_ptr<unsigned char> response ) {
286 return Send( NOCHANGE, NOCHANGE, response_len, response.get(), RESPONSE );
289 bool Message::Send_response( int response_len, unsigned char* response ) {
290 return Send( NOCHANGE, NOCHANGE, response_len, response, RESPONSE );
295 Send a message based on message type routing.
297 Payload can be null and the assumption will be that the message payload
298 was updated in place and no additional copy is needed before sending the message.
300 Return is a new mbuf suitable for sending another message, or the original buffer with
301 a bad state sent if there was a failure.
303 bool Message::Send_msg( int mtype, int subid, int payload_len, std::unique_ptr<unsigned char> payload ) {
304 return Send( mtype, subid, payload_len, payload.get(), MESSAGE );
307 bool Message::Send_msg( int mtype, int subid, int payload_len, unsigned char* payload ) {
308 return Send( mtype, subid, payload_len, payload, MESSAGE );
312 Similar send functions that allow the message type/subid to remain unchanged
314 bool Message::Send_msg( int payload_len, std::unique_ptr<unsigned char> payload ) {
315 return Send( NOCHANGE, NOCHANGE, payload_len, payload.get(), MESSAGE );
318 bool Message::Send_msg( int payload_len, unsigned char* payload ) {
319 return Send( NOCHANGE, NOCHANGE, payload_len, payload, MESSAGE );