int sub_getascii(FILE* stream, ot_queue* msg) { char next; int bytes_written; bytes_written = q_length(msg); while (1) { next = fgetc(stream); if (next == '"') { break; } if (next == '\\') { switch (fgetc(stream)) { case 'a': next = '\a'; break; case '\\': next = '\\'; break; case 'b': next = '\b'; break; case 'r': next = '\r'; break; case '"': next = '\"'; break; case 'f': next = '\f'; break; case 't': next = '\t'; break; case 'n': next = '\n'; break; case '0': next = '\0'; break; case '\'': next = '\''; break; case 'v': next = '\v'; break; case '?': next = '\?'; break; } } q_writebyte(msg, next); } bytes_written = (q_length(msg) - bytes_written); return bytes_written; }
int q_add(void *qt, void *func, void *arg) { ASSERT(qt); ASSERT(func); /*arg possible NULL*/ Q_t *q = (Q_t*)qt; pthread_mutex_lock(&q->mutex); if (OK == q_isfull(q)) { pthread_mutex_unlock(&q->mutex); return ERROR; } ASSERT(q->last->func == NULL); q->last->func = func; q->last->arg = arg; q->last++; if (q->last == q->first + 1) { ASSERT(1 == q_length(q)); dump(L_DEBUG, "Queue send signal, has data"); pthread_cond_signal(&q->has_data_cond); } if (q->last == q->head + q->size) q->last = q->head; dump(L_DEBUG, "Add Queue Length %d", q_length(q)); pthread_mutex_unlock(&q->mutex); return OK; }
int sub_getdecblock(void* stream, ot_queue* msg) { int status = 0; int bytes_written = q_length(msg); while (status == 0) { sub_getdecnum(&status, stream, msg); } bytes_written = q_length(msg) - bytes_written; return bytes_written; }
int sub_gethexblock(FILE* stream, ot_queue* msg) { int status = 0; int bytes_written; bytes_written = q_length(msg); while (status == 0) { sub_gethexnum(&status, stream, msg); } bytes_written = q_length(msg) - bytes_written; return bytes_written; }
/* Destructor: free up the storage used by the queue. */ void q_destroy(queue q) { /* get rid of all the elements in the queue */ while ( q_length(q) > 0 ) { q_remove(q); } free(q); }
/* Return the element at index in the queue, and deletes it from inside the queue. */ int q_delete_item(queue q, int index) { assert(0 <= index && index < q_length(q)); int val; if(index == 0) { q_node_t *new_head = q->head->next; val = q->head->val; free(q->head); q->head = new_head; if (q->length == 0) { q->tail = 0; } } else { q_node_t *previousNode = q_get_node(q, index - 1); q_node_t *newNext = previousNode->next->next; val = previousNode->next->val; free(previousNode->next); previousNode->next = newNext; if(previousNode->next == 0){ q->tail = previousNode; } } q->length--; return val; }
OT_WEAK ot_u16 otapi_put_isf_comp(ot_u8* status, isfcomp_tmpl* isfcomp) { q_writebyte(&txq, isfcomp->isf_id); sub_put_isf_offset(isfcomp->is_series, isfcomp->offset); *status = 1; return q_length(&txq); }
OT_WEAK ot_u16 otapi_put_isf_call(ot_u8* status, isfcall_tmpl* isfcall) { q_writebyte(&txq, isfcall->max_return); q_writebyte(&txq, isfcall->isf_id); sub_put_isf_offset(isfcall->is_series, isfcall->offset); *status = 1; return q_length(&txq); }
OT_WEAK ot_u16 otapi_put_error_tmpl(ot_u8* status, error_tmpl* error) { ///@todo this feature is being abandoned in DASH7 Mode 2 q_writebyte(&txq, error->code); q_writebyte(&txq, error->subcode); *status = 1; return q_length(&txq); }
/* add val to the end of the queue */ void q_add(queue q, int val) { //TODO: implement a function that //returns the maximum capacity of the queue assert(q_length(q) < q->buf_len); q->buf[(q->start + q->length) % q->buf_len] = val; q->length += 1; }
/* add val to the end of the queue */ void q_add(queue q, int valx, int valy) { //~ Serial.print("qlength??");Serial.println(q->length); //~ Serial.print("qbuflength??");Serial.println(q->buf_len); assert(q_length(q) < q->buf_len); q->x[(q->start + q->length) % q->buf_len] = valx; q->y[(q->start + q->length) % q->buf_len] = valy; q->length = q->length + 1; }
OT_WEAK ot_u16 otapi_put_udp_tmpl(ot_u8* status, udp_tmpl* udp) { /// There is no error/exception handling in this implementation, but it is /// possible to add in the future q_writebyte(&txq, udp->src_port); q_writebyte(&txq, udp->dst_port); q_writestring(&txq, udp->data, udp->data_length); *status = 1; return q_length(&txq); }
OT_WEAK void alp_stream_queue(ot_queue* out_q, void* data_type) { if _PTR_TEST(data_type) { ot_int length; length = q_length((ot_queue*)data_type); q_writeshort(out_q, ((ot_queue*)data_type)->alloc); q_writeshort(out_q, ((ot_queue*)data_type)->options.ushort); q_writeshort(out_q, length); q_writestring(out_q, ((ot_queue*)data_type)->front, length); } }
OT_WEAK ot_uint rm2_pkt_duration(ot_queue* pkt_q) { /// Wrapper function for rm2_scale_codec that adds some slop overhead /// Slop = preamble bytes + sync bytes + ramp-up + ramp-down + padding ot_uint pkt_bytes; pkt_bytes = q_length(pkt_q); pkt_bytes += RF_PARAM_PKT_OVERHEAD; // If packet is using RS coding, adjust by the nominal rate (4/5). if (pkt_q->front[1] & 0x40) { pkt_bytes += (pkt_bytes+3)>>2; }
OT_WEAK ot_u16 otapi_put_query_tmpl(ot_u8* status, query_tmpl* query) { q_writebyte(&txq, query->length); q_writebyte(&txq, query->code); if (query->code & 0x80) { q_writestring(&txq, query->mask, query->length); } q_writestring(&txq, query->value, query->length); *status = 1; return q_length(&txq); }
OT_WEAK ot_u16 otapi_put_ack_tmpl(ot_u8* status, ack_tmpl* ack) { ot_int i; ot_u8* data_ptr = ack->list; ot_u8* limit = txq.back - ack->length; for (i=0; (i < ack->count) && (txq.putcursor < limit); \ i+=ack->length, data_ptr+=ack->length ) { q_writestring(&txq, data_ptr, ack->length); } *status = (ot_u8)i; return q_length(&txq); }
OT_WEAK ot_u16 otapi_put_isf_return(ot_u8* status, isfcall_tmpl* isfcall) { ot_queue local_q; ot_u8 lq_data[4]; q_init(&local_q, lq_data, 4); q_writebyte(&local_q, (ot_u8)isfcall->max_return); q_writebyte(&local_q, (ot_u8)isfcall->isf_id); sub_put_isf_offset(isfcall->is_series, isfcall->offset); ///@note user_id is set to NULL here. This stipulates that the API is not /// ever going to be called by a non root user. So, the application /// layer should perform proper authentication of the user if neeeded. *status = (m2qp_isf_call(isfcall->is_series, &local_q, NULL) >= 0); return q_length(&txq); }
void q_remove(Q_t *q, void** func, void** arg) { ASSERT(q); ASSERT(q->first->func); ASSERT(func); ASSERT(arg); *func = q->first->func; *arg = q->first->arg; q->first->func = NULL; q->first->arg = NULL; q->first++; if (q->first == q->head + q->size) q->first = q->head; dump(L_DEBUG, "Remove Queue Length %d", q_length(q)); //q_print(q, print_p); }
q_node_t * q_get_node(queue q, int index) { assert(0 <= index && index < q->length); q_node_t *node; int tailIndex = q_length(q)-1; if(index == tailIndex) { node = q->tail; } else { int pos = 0; node = q->head; while(pos < index) { node = node->next; pos++; } } return node; }
void q_print(ot_queue* q) { int length; int i; int row; length = q_length(q); printf("Queue Length/Alloc: %d/%d\n", length, q->alloc); printf("Queue Getcursor: %d\n", (int)(q->getcursor-q->front)); printf("Queue Putcursor: %d\n", (int)(q->putcursor-q->front)); for (i=0, row=0; length>0; ) { length -= 8; row += (length>0) ? 8 : 8+length; printf("%04X: ", i); for (; i<row; i++) { printf("%02X ", q->front[i]); } printf("\n"); } printf("\n"); }
OT_WEAK ot_u16 otapi_put_dialog_tmpl(ot_u8* status, dialog_tmpl* dialog) { if (dialog == NULL) { ///@todo "15" is hard-coded timeout. Have this be a constant dll.comm.rx_timeout = (m2qp.cmd.ext & 2) ? 0 : 15; q_writebyte(&txq, (ot_u8)dll.comm.rx_timeout); } else { // Place dialog with timeout dll.comm.rx_timeout = otutils_calc_timeout(dialog->timeout); dialog->timeout |= (dialog->channels == 0) << 7; // 0 or 0x80 q_writebyte(&txq, dialog->timeout); // Write response list if (dialog->channels != 0) { dll.comm.rx_channels = dialog->channels; dll.comm.rx_chanlist = dialog->chanlist; q_writestring(&txq, dialog->chanlist, dialog->channels); } } *status = 1; return q_length(&txq); }
OT_WEAK ot_u16 otapi_put_command_tmpl(ot_u8* status, command_tmpl* command) { /// Check Opcodes to make sure this one is supported /// @todo base this on app_config.h settings. Currently this is rudimentary /// and hard-coded. It just filters out Datastream and non-existing codes if (command->opcode > 15) { // command extension, not present at the moment *status = 0; return 0; } dll.comm.csmaca_params |= command->type & M2_CSMACA_A2P; m2qp.cmd.code = command->type | command->opcode; m2qp.cmd.code |= (command->extension != 0) << 7; m2qp.cmd.ext = command->extension; q_writebyte(&txq, m2qp.cmd.code); if (m2qp.cmd.ext != 0) { q_writebyte(&txq, m2qp.cmd.ext); } *status = 1; return q_length(&txq); }
/* return the item at the front of the queue */ int q_front(queue q) { assert(q_length(q) > 0); return q->buf[q->start]; }
/* print the contents of a queue from head to tail going left to right. */ void q_printf(queue q) { for (int i=0; i < q_length(q); i++) { printf("%d ", q_get_item(q, i)); } }
unsigned long si_length(sorted_intlist si) { return(q_length(si->q)); }
/* Get the element of the queue at position index, where the head of the queue is position 0, and the tail is at position length(q)-1 */ int q_get_item(queue q, int index) { assert(0 <= index && index < q_length(q)); return q_get_node(q, index)->val; }
int main(int argc, char *argv[]) { /* test harness */ int tests_passed = 0; int tests_failed = 0; /* create a queue with a size hint */ printf("Creating queue\n"); queue qp = q_create(20); /* how do we see if queue was propery initialized? */ /* add and remove one element */ int e1 = 42; q_add(qp, e1); printf("Test 1: "); q_printf(qp); printf("\n"); /* length should have gone up by one */ if ( q_length(qp) != 1 ) { printf("Test 1 failed, length %d should be 1\n", q_length(qp)); tests_failed++; } else { printf("Test 1 passed.\n"); tests_passed++; } printf("Test 2: "); int e2 = q_remove(qp); q_printf(qp); printf("\n"); if ( q_length(qp) != 0 ) { printf("Test 2.1 failed, length %d should be 0\n", q_length(qp)); tests_failed++; } else { printf("Test 2.1 passed.\n"); tests_passed++; } if ( e1 != e2 ) { printf("Test 2.2 failed, e2 %d should equal e1 %d\n", e2, e1); tests_failed++; } else { printf("Test 2.2 passed.\n"); tests_passed++; } printf("Test 3: "); for (int i=1; i <= 10; i++) { q_add(qp, i); } q_printf(qp); printf("\n"); for (int i=1; i<= 10; i++) { e1 = q_remove(qp); if ( q_length(qp) != 10-i ) { printf("Test 3.1 failed, length %d should be %d\n", q_length(qp), 10-i); tests_failed++; } else { tests_passed++; } if ( e1 != i ) { printf("Test 3.2 failed, element %d should be %d\n", e1, i); tests_failed++; } else { tests_passed++; } } printf("Test 4: "); for (int i=1; i <= 10; i++) { q_add(qp, i); } q_printf(qp); printf("\n"); for (int i=0; i < 10; i++) { int expected = i + 1; int actual = q_get_item(qp, i); if(expected != actual) { printf("Test 4 failed, element #%d should be %d but was %d\n", i, expected, actual); tests_failed++; } else { tests_passed++; } } // Reset to empty for (int i=1; i <= 10; i++) { q_remove(qp); } q_add(qp, e1); printf("Test 5.1: "); q_printf(qp); printf("\n"); /* length should have gone up by one */ if ( q_length(qp) != 1 ) { printf("Test 5.1 failed, length %d should be 1 before deletion\n", q_length(qp)); tests_failed++; } else { int actual = q_delete_item(qp, 0); if( q_length(qp) != 0) { printf("Test 5.1 failed, length %d should be 0 after deletion\n", q_length(qp)); tests_failed++; } else if(actual != e1) { printf("Test 5.1 failed, element retrieved from deleted: Expected: %d; Actual: %d\n", e1, actual); tests_failed++; } else { printf("Test 5.1 passed.\n"); tests_passed++; } } printf("Test 5.2: "); for (int i=1; i <= 10; i++) { q_add(qp, i); } q_printf(qp); printf("\n"); int deletedElement; deletedElement = q_delete_item(qp, 4); if(deletedElement != 5) { printf("Test 5.2 failed, element retrieved from deleted: Expected: 5; Actual: %d\n", deletedElement); tests_failed++; } deletedElement = q_delete_item(qp, 4); if(deletedElement != 6) { printf("Test 5.2 failed, element retrieved from deleted: Expected: 6; Actual: %d\n", deletedElement); tests_failed++; } q_printf(qp); printf("\n"); if( q_length(qp) != 8) { printf("Test 5.2 failed, length %d should be 8 after deletion\n", q_length(qp)); tests_failed++; } else { if(q_get_item(qp, 4) != 7) { printf("Test 5.2 failed, value of element at index 4 after deletion: Expected: 7; Actual: %d\n", q_get_item(qp, 4)); tests_failed++; } else { printf("Test 5.2 passed.\n"); tests_passed++; } } /* a fatal test */ if ( 0 ) { printf("Test 4: remove on empty queue\n"); e2 = q_remove(qp); tests_failed++; } printf("Tests Passed: %d\n", tests_passed); printf("Tests Failed: %d\n", tests_failed); }