//////////////////////////////////////////////////////////////////// // Discovers a route to the destination (if necessary), sends and // waits for delivery to the next hop (but not for delivery to the final destination) uint8_t RHMesh::sendtoWait(uint8_t* buf, uint8_t len, uint8_t address) { if (len > RH_MESH_MAX_MESSAGE_LEN) return RH_ROUTER_ERROR_INVALID_LENGTH; RoutingTableEntry* route = getRouteTo(address); if (!route && !doArp(address)) return RH_ROUTER_ERROR_NO_ROUTE; // Now have a route. Contruct an applicaiotn layer message and dend it via that route MeshApplicationMessage* a = (MeshApplicationMessage*)&_tmpMessage; a->header.msgType = RH_MESH_MESSAGE_TYPE_APPLICATION; memcpy(a->data, buf, len); return RHRouter::sendtoWait(_tmpMessage, sizeof(RHMesh::MeshMessageHeader) + len, address); }
uint8_t RF22Router::route(RoutedMessage* message, uint8_t messageLen) { // Reliably deliver it if possible. See if we have a route: uint8_t next_hop = RF22_BROADCAST_ADDRESS; if (message->header.dest != RF22_BROADCAST_ADDRESS) { RoutingTableEntry* route = getRouteTo(message->header.dest); if (!route) return RF22_ROUTER_ERROR_NO_ROUTE; next_hop = route->next_hop; } if (!RF22ReliableDatagram::sendtoWait((uint8_t*)message, messageLen, next_hop)) return RF22_ROUTER_ERROR_UNABLE_TO_DELIVER; return RF22_ROUTER_ERROR_NONE; }
//////////////////////////////////////////////////////////////////// // Discovers a route to the destination (if necessary), sends and // waits for delivery to the next hop (but not for delivery to the final destination) uint8_t RF22Mesh::sendtoWait(uint8_t* buf, uint8_t len, uint8_t address) { freeMem( F( "RF22Mesh::sendtoWait" ) ); uint8_t frags = 0, ret; uint16_t frag_len = 0, len_remain = (uint16_t) len; if (len > GLOBAL_BUFFER_SIZE) return RF22_ROUTER_ERROR_INVALID_LENGTH; if( address != RF22_BROADCAST_ADDRESS ) { RoutingTableEntry* route = getRouteTo(address); if( !route && !doArp( address ) ) { return RF22_ROUTER_ERROR_NO_ROUTE; } } frags = ( len / RF22_MESH_MAX_MESSAGE_LEN ) + 1; #ifdef CLIENT Serial.print( F( "frags: " ) ); Serial.println( frags ); #endif for( uint8_t i = 0; i < frags; i++ ) { // Now have a route. Contruct an applicaiotn layer message and dend it via that route MeshApplicationMessage* a = (MeshApplicationMessage*)&_tmpMessage; a->header.msgType = RF22_MESH_MESSAGE_TYPE_APPLICATION; if( i < frags - 1 ) { a->header.frag = 1; frag_len = RF22_MESH_MAX_MESSAGE_LEN; len_remain -= frag_len; } else { a->header.frag = 0; frag_len = len_remain; len_remain -= frag_len; //frag_len = len < ( frags * RF22_MESH_MAX_MESSAGE_LEN ) ? len : len - ( frags * RF22_MESH_MAX_MESSAGE_LEN ); } #ifdef CLIENT Serial.print( F( "frag_len: " ) ); Serial.println( frag_len ); #endif a->header.seqno = i; memcpy( a->data, buf + ( i * RF22_MESH_MAX_MESSAGE_LEN ), frag_len ); #ifdef CLIENT for( int i = 0; i < frag_len; i++ ) { Serial.print( a->data[i], HEX ); Serial.print( F( ", " ) ); } Serial.println( F( "" ) ); #endif ret = RF22Router::sendtoWait(_tmpMessage, sizeof(RF22Mesh::MeshMessageHeader) + frag_len, address); if( ret != RF22_ROUTER_ERROR_NONE ) { return ret; } } return 0; }
OsStatus ForwardRules::parseFieldMatchContainer(const SipMessage& request, UtlString& routeToString, bool& authRequired, TiXmlNode* methodMatchNode, TiXmlNode* previousFieldMatchNode) { OsStatus getRouteFound = OS_FAILED; UtlBoolean fieldPatternFound = false; TiXmlNode* fieldMatchNode = previousFieldMatchNode; while ( (fieldMatchNode = methodMatchNode->IterateChildren( fieldMatchNode)) && (getRouteFound != OS_SUCCESS) ) { UtlBoolean fieldNameMatches = false; UtlBoolean noFieldPatternRequired = false; if(fieldMatchNode && fieldMatchNode->Type() != TiXmlNode::ELEMENT) { continue; } UtlString tagValue = fieldMatchNode->Value(); if(tagValue.compareTo(XML_TAG_FIELDMATCH) != 0 ) { continue; } TiXmlElement* fieldMatchElement = fieldMatchNode->ToElement(); TiXmlNode* fieldPatternNode = NULL; UtlBoolean fieldPatternPresent = false; UtlString fieldName; const char* fieldValuePtr = NULL; //check for fieldName parameter , if present check if it matches if(fieldMatchElement->Attribute(XML_ATT_FIELDNAME)) { UtlString fieldNameXml = fieldMatchElement->Attribute(XML_ATT_FIELDNAME); // If field name is specified, // check if it exists in the message if(!fieldNameXml.isNull()) { fieldValuePtr = request.getHeaderValue(0, fieldNameXml.data()); if(fieldValuePtr) { fieldNameMatches = true; } } } else { noFieldPatternRequired = true; } if(fieldNameMatches && !noFieldPatternRequired) { //get the user text value from it for( fieldPatternNode = fieldMatchElement->FirstChild( XML_TAG_FIELDPATTERN); fieldPatternNode; fieldPatternNode = fieldPatternNode->NextSibling(XML_TAG_FIELDPATTERN ) ) { fieldPatternPresent = true; TiXmlElement* fieldPatternElement = fieldPatternNode->ToElement(); TiXmlNode* fieldPatternText = fieldPatternElement->FirstChild(); if(fieldPatternText) { try { RegEx fieldPatternXml(fieldPatternText->Value(),PCRE_ANCHORED); if (fieldPatternXml.Search(fieldValuePtr)) { fieldPatternFound = true; } } catch(const char * ErrorMsg) { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "Illegal regular expression <fieldPattern>%s</fieldPattern>" " in forwardingrules.xml: %s", fieldPatternText->Value() ,ErrorMsg ); } } } } if( (fieldNameMatches && (fieldPatternFound || !fieldPatternPresent)) || noFieldPatternRequired ) { //get the routeTo field getRouteFound = getRouteTo(routeToString, authRequired, fieldMatchNode); } } return getRouteFound; }
OsStatus ForwardRules::parseMethodMatchContainer(const SipMessage& request, UtlString& routeToString, bool& authRequired, TiXmlNode* routeMatchNode, TiXmlNode* previousMethodMatchNode) { OsStatus fieldMatchFound = OS_FAILED; UtlString method; request.getRequestMethod(&method); TiXmlNode* methodMatchNode = previousMethodMatchNode; TiXmlElement* routeMatchElement = routeMatchNode->ToElement(); // Iterate through the children of the routeFrom container // looking for methodMatch elements while ( (methodMatchNode = routeMatchElement->IterateChildren( methodMatchNode)) && (fieldMatchFound != OS_SUCCESS) ) { // Skip non-elements if(methodMatchNode && methodMatchNode->Type() != TiXmlNode::ELEMENT) { continue; } // Skip non-methodMatch elements UtlString tagValue = methodMatchNode->Value(); if(tagValue.compareTo(XML_TAG_METHODMATCH) != 0 ) { continue; } //found methodPattern tag TiXmlElement* methodMatchElement = methodMatchNode->ToElement(); TiXmlNode* methodPatternNode = NULL; // Iteratore through the children of the methodMatch element // looking for the first methodPattern element that matches for( methodPatternNode = methodMatchElement->FirstChild( XML_TAG_METHODPATTERN); methodPatternNode; methodPatternNode = methodPatternNode->NextSibling(XML_TAG_METHODPATTERN ) ) { // Skip non-elements if(methodPatternNode && methodPatternNode->Type() != TiXmlNode::ELEMENT) { continue; } TiXmlElement* methodPatternElement = methodPatternNode->ToElement(); // Get the value contained in the methodPattern element TiXmlNode* methodPatternText = methodPatternElement->FirstChild(); if(methodPatternText && methodPatternText->Type() == TiXmlNode::TEXT) { TiXmlText* XmlMethod = methodPatternText->ToText(); if (XmlMethod) { // If the method of the request matches the method in // the methodMatch element UtlString methodString = XmlMethod->Value(); if (methodString.compareTo(method, UtlString::ignoreCase) == 0 ) { // Found a matching method, see if there is a fieldMatch // with a fieldName attribute that matches the fields // in the message fieldMatchFound = parseFieldMatchContainer(request, routeToString, authRequired, methodMatchNode); if(fieldMatchFound == OS_SUCCESS) { break; } // None of the fields matched, see if the methodMatch // element has an immediate child routeTo element. // This is the "default" if none of the fieldMatches // matched. else { fieldMatchFound = getRouteTo(routeToString, authRequired, methodMatchElement); if(fieldMatchFound == OS_SUCCESS) { break; } } } } } } } if(fieldMatchFound == OS_FAILED) { // if none of the method match were successfull or if no methodMatch node present // get the default routeTo for this routeNode. fieldMatchFound = getRouteTo(routeToString, authRequired, routeMatchNode); } return fieldMatchFound; }